blob: 618dd50c27fc98582f32d254de07605cc30dab24 [file] [edit]
// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import path from 'node:path';
// Shared helper for plugins that synthesise a module's source on the fly but
// expose it via a normal relative import (typed by a colocated .d.ts).
//
// `modules` maps an absolute path (no extension) — e.g. <SRC>/plugins/index —
// to a function that returns the module source. resolveId intercepts both
// file-style imports ('../base/version') and directory-style imports
// ('../plugins' → '../plugins/index') before Vite's filesystem resolver runs.
export function makeSynthModulePlugin({name, modules}) {
const PREFIX = '\0' + name + ':';
return {
name,
enforce: 'pre',
resolveId(source, importer) {
if (!importer || !source.startsWith('.')) return null;
const stripped = source.replace(/\.(ts|js)$/, '');
const abs = path.resolve(path.dirname(importer), stripped);
for (const candidate of [abs, path.join(abs, 'index')]) {
if (candidate in modules) return PREFIX + candidate;
}
},
load(id) {
if (!id.startsWith(PREFIX)) return;
const gen = modules[id.slice(PREFIX.length)];
if (gen) return gen(this);
},
};
}