@hirarijs/loader 1.0.18 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-HIW3PA5X.js +367 -0
- package/dist/chunk-VGNNMSLY.js +15 -0
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +4 -2
- package/dist/loader.cjs +58 -1
- package/dist/loader.js +1 -1
- package/dist/register-auto.js +2 -2
- package/dist/register.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: [
|
|
7
|
+
"@hirarijs/loader-ts",
|
|
8
|
+
"@hirarijs/loader-tsx",
|
|
9
|
+
"@hirarijs/loader-vue",
|
|
10
|
+
"@hirarijs/loader-cjs-interop"
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
14
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
return { ...DEFAULT_CONFIG };
|
|
17
|
+
}
|
|
18
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
const loaderConfig = parsed.loader || {};
|
|
26
|
+
return {
|
|
27
|
+
...DEFAULT_CONFIG,
|
|
28
|
+
...loaderConfig,
|
|
29
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getFormat(config) {
|
|
33
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
38
|
+
var BYPASS_FLAG = "__hirari_loader_bypass__";
|
|
39
|
+
var BYPASS_PREFIX = "hirari-bypass:";
|
|
40
|
+
|
|
41
|
+
// src/plugin-manager.ts
|
|
42
|
+
import { spawnSync } from "child_process";
|
|
43
|
+
import fs2 from "fs";
|
|
44
|
+
import path2 from "path";
|
|
45
|
+
import { createRequire } from "module";
|
|
46
|
+
var PACKAGE_MANAGERS = [
|
|
47
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
48
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
49
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
50
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
51
|
+
];
|
|
52
|
+
function detectPackageManager(cwd) {
|
|
53
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
54
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
55
|
+
}
|
|
56
|
+
return { command: "npm", args: ["install"] };
|
|
57
|
+
}
|
|
58
|
+
function tryRequire(moduleId, cwd) {
|
|
59
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
60
|
+
const loaded = req(moduleId);
|
|
61
|
+
return loaded && (loaded.default || loaded);
|
|
62
|
+
}
|
|
63
|
+
function install(pkg, cwd) {
|
|
64
|
+
const pm = detectPackageManager(cwd);
|
|
65
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
66
|
+
cwd,
|
|
67
|
+
stdio: "inherit",
|
|
68
|
+
env: process.env
|
|
69
|
+
});
|
|
70
|
+
if (result.error) {
|
|
71
|
+
throw result.error;
|
|
72
|
+
}
|
|
73
|
+
if (result.status !== 0) {
|
|
74
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function resolvePlugins(config, cwd) {
|
|
78
|
+
const plugins = [];
|
|
79
|
+
for (const pluginName of config.plugins || []) {
|
|
80
|
+
let loaded = null;
|
|
81
|
+
try {
|
|
82
|
+
loaded = tryRequire(pluginName, cwd);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (config.autoInstall) {
|
|
85
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
86
|
+
install(pluginName, cwd);
|
|
87
|
+
loaded = tryRequire(pluginName, cwd);
|
|
88
|
+
} else {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!loaded) continue;
|
|
95
|
+
plugins.push({
|
|
96
|
+
plugin: loaded,
|
|
97
|
+
options: config.pluginOptions?.[pluginName]
|
|
98
|
+
});
|
|
99
|
+
if (config.debug) {
|
|
100
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return plugins;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/runtime.ts
|
|
107
|
+
import fs3 from "fs";
|
|
108
|
+
import module from "module";
|
|
109
|
+
import path3 from "path";
|
|
110
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
111
|
+
import { addHook } from "pirates";
|
|
112
|
+
import * as sourceMapSupport from "source-map-support";
|
|
113
|
+
var map = {};
|
|
114
|
+
var packageTypeCache = /* @__PURE__ */ new Map();
|
|
115
|
+
var EXTENSION_CANDIDATES = [
|
|
116
|
+
".ts",
|
|
117
|
+
".mts",
|
|
118
|
+
".cts",
|
|
119
|
+
".tsx",
|
|
120
|
+
".jsx",
|
|
121
|
+
".vue",
|
|
122
|
+
".js",
|
|
123
|
+
".mjs",
|
|
124
|
+
".cjs"
|
|
125
|
+
];
|
|
126
|
+
function installSourceMaps() {
|
|
127
|
+
sourceMapSupport.install({
|
|
128
|
+
handleUncaughtExceptions: false,
|
|
129
|
+
environment: "node",
|
|
130
|
+
retrieveSourceMap(file) {
|
|
131
|
+
if (map[file]) {
|
|
132
|
+
return { url: file, map: map[file] };
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
139
|
+
function findNearestPackageType(filename) {
|
|
140
|
+
const dir = path3.dirname(filename);
|
|
141
|
+
if (packageTypeCache.has(dir)) return packageTypeCache.get(dir);
|
|
142
|
+
let current = dir;
|
|
143
|
+
while (true) {
|
|
144
|
+
const candidate = path3.join(current, "package.json");
|
|
145
|
+
if (fs3.existsSync(candidate)) {
|
|
146
|
+
try {
|
|
147
|
+
const pkg = JSON.parse(fs3.readFileSync(candidate, "utf8"));
|
|
148
|
+
const type = pkg && pkg.type === "module" ? "module" : "commonjs";
|
|
149
|
+
packageTypeCache.set(dir, type);
|
|
150
|
+
return type;
|
|
151
|
+
} catch {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const parent = path3.dirname(current);
|
|
156
|
+
if (parent === current) break;
|
|
157
|
+
current = parent;
|
|
158
|
+
}
|
|
159
|
+
packageTypeCache.set(dir, "commonjs");
|
|
160
|
+
return "commonjs";
|
|
161
|
+
}
|
|
162
|
+
function inferFormat(filename, fallback) {
|
|
163
|
+
const ext = path3.extname(filename);
|
|
164
|
+
if (ext === ".mjs" || ext === ".mts" || ext === ".mtsx") return "esm";
|
|
165
|
+
if (ext === ".cjs" || ext === ".cts") return "cjs";
|
|
166
|
+
if (ext === ".js" || ext === ".ts" || ext === ".tsx" || ext === ".jsx" || ext === ".vue") {
|
|
167
|
+
const pkgType = findNearestPackageType(filename);
|
|
168
|
+
return pkgType === "module" ? "esm" : "cjs";
|
|
169
|
+
}
|
|
170
|
+
return fallback;
|
|
171
|
+
}
|
|
172
|
+
function createRuntime(cwd = process.cwd()) {
|
|
173
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
174
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
175
|
+
installSourceMaps();
|
|
176
|
+
return {
|
|
177
|
+
cwd,
|
|
178
|
+
loaderConfig,
|
|
179
|
+
resolvedPlugins,
|
|
180
|
+
format: getFormat(loaderConfig)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function applyPlugin(code, filename, runtime) {
|
|
184
|
+
let currentCode = code;
|
|
185
|
+
let currentFormat = runtime.format;
|
|
186
|
+
let lastResult = null;
|
|
187
|
+
for (const match of runtime.resolvedPlugins) {
|
|
188
|
+
if (!match.plugin.match(filename)) continue;
|
|
189
|
+
const ctx = {
|
|
190
|
+
format: currentFormat,
|
|
191
|
+
loaderConfig: runtime.loaderConfig,
|
|
192
|
+
pluginOptions: match.options
|
|
193
|
+
};
|
|
194
|
+
const result = match.plugin.transform(currentCode, filename, ctx);
|
|
195
|
+
if (runtime.loaderConfig.debug) {
|
|
196
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
197
|
+
}
|
|
198
|
+
if (result.map) {
|
|
199
|
+
map[filename] = result.map;
|
|
200
|
+
}
|
|
201
|
+
if (result.format) {
|
|
202
|
+
currentFormat = result.format;
|
|
203
|
+
}
|
|
204
|
+
if (result.continue) {
|
|
205
|
+
lastResult = result;
|
|
206
|
+
if (result.code) {
|
|
207
|
+
currentCode = result.code;
|
|
208
|
+
}
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
if (lastResult) {
|
|
214
|
+
return {
|
|
215
|
+
code: lastResult.code ?? currentCode,
|
|
216
|
+
map: lastResult.map,
|
|
217
|
+
format: lastResult.format ?? currentFormat
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
if (runtime.loaderConfig.debug) {
|
|
221
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
222
|
+
}
|
|
223
|
+
return { code: currentCode };
|
|
224
|
+
}
|
|
225
|
+
function pickPlugin(filename, runtime) {
|
|
226
|
+
return runtime.resolvedPlugins.find(({ plugin }) => plugin.match(filename));
|
|
227
|
+
}
|
|
228
|
+
function collectExtensions(plugins) {
|
|
229
|
+
const set = /* @__PURE__ */ new Set();
|
|
230
|
+
for (const { plugin } of plugins) {
|
|
231
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
232
|
+
}
|
|
233
|
+
return Array.from(set);
|
|
234
|
+
}
|
|
235
|
+
function registerRequireHooks(runtime) {
|
|
236
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
237
|
+
const compile = (code, filename) => {
|
|
238
|
+
if (globalThis[BYPASS_FLAG]) {
|
|
239
|
+
return code;
|
|
240
|
+
}
|
|
241
|
+
const result = applyPlugin(code, filename, runtime);
|
|
242
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
243
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
244
|
+
return `${banner}${result.code}`;
|
|
245
|
+
}
|
|
246
|
+
return result.code;
|
|
247
|
+
};
|
|
248
|
+
const revert = addHook(compile, {
|
|
249
|
+
exts: extensions,
|
|
250
|
+
ignoreNodeModules: false
|
|
251
|
+
});
|
|
252
|
+
const extensionsObj = module.Module._extensions;
|
|
253
|
+
const jsHandler = extensionsObj[".js"];
|
|
254
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
255
|
+
try {
|
|
256
|
+
return jsHandler.call(this, mod, filename);
|
|
257
|
+
} catch (error) {
|
|
258
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
259
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
260
|
+
const result = applyPlugin(src, filename, runtime);
|
|
261
|
+
mod._compile(result.code, filename);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
return () => {
|
|
268
|
+
revert();
|
|
269
|
+
extensionsObj[".js"] = jsHandler;
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
async function loaderResolve(specifier, context, next, runtime) {
|
|
273
|
+
const parentUrl = context && context.parentURL;
|
|
274
|
+
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? path3.dirname(fileURLToPath(parentUrl)) : process.cwd();
|
|
275
|
+
if (specifier.startsWith(BYPASS_PREFIX)) {
|
|
276
|
+
const target = specifier.slice(BYPASS_PREFIX.length);
|
|
277
|
+
const url = target.startsWith("file:") ? target : pathToFileURL(target).href;
|
|
278
|
+
return { url, shortCircuit: true };
|
|
279
|
+
}
|
|
280
|
+
for (const match of runtime.resolvedPlugins) {
|
|
281
|
+
if (typeof match.plugin.resolve !== "function") continue;
|
|
282
|
+
const importer = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? fileURLToPath(parentUrl) : null;
|
|
283
|
+
const ctx = {
|
|
284
|
+
format: runtime.format,
|
|
285
|
+
loaderConfig: runtime.loaderConfig,
|
|
286
|
+
pluginOptions: match.options
|
|
287
|
+
};
|
|
288
|
+
const res = match.plugin.resolve(specifier, importer, ctx);
|
|
289
|
+
if (res && res.url) {
|
|
290
|
+
const url = res.url.startsWith("file:") ? res.url : pathToFileURL(res.url).href;
|
|
291
|
+
return { url, shortCircuit: res.shortCircuit !== false, format: res.format };
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const tryResolve = (basePath, note) => {
|
|
295
|
+
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
296
|
+
const candidate = basePath + ext2;
|
|
297
|
+
if (fs3.existsSync(candidate) && fs3.statSync(candidate).isFile()) {
|
|
298
|
+
const url = pathToFileURL(candidate).href;
|
|
299
|
+
if (runtime.loaderConfig.debug) {
|
|
300
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
301
|
+
}
|
|
302
|
+
return { url, shortCircuit: true };
|
|
303
|
+
}
|
|
304
|
+
const indexCandidate = path3.join(basePath, "index" + ext2);
|
|
305
|
+
if (fs3.existsSync(indexCandidate) && fs3.statSync(indexCandidate).isFile()) {
|
|
306
|
+
const url = pathToFileURL(indexCandidate).href;
|
|
307
|
+
if (runtime.loaderConfig.debug) {
|
|
308
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
309
|
+
}
|
|
310
|
+
return { url, shortCircuit: true };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
};
|
|
315
|
+
if (!path3.extname(specifier) && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:")) && !specifier.startsWith("node:")) {
|
|
316
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(specifier) : specifier.startsWith("/") ? specifier : path3.resolve(baseDir, specifier);
|
|
317
|
+
const res = tryResolve(basePath, "extless");
|
|
318
|
+
if (res) return res;
|
|
319
|
+
}
|
|
320
|
+
const ext = path3.extname(specifier);
|
|
321
|
+
if ((ext === ".js" || ext === ".mjs" || ext === ".cjs") && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:"))) {
|
|
322
|
+
const withoutExt = specifier.slice(0, -ext.length);
|
|
323
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(withoutExt) : specifier.startsWith("/") ? withoutExt : path3.resolve(baseDir, withoutExt);
|
|
324
|
+
const res = tryResolve(basePath, "fallback-js");
|
|
325
|
+
if (res) return res;
|
|
326
|
+
}
|
|
327
|
+
if (next) return next(specifier, context);
|
|
328
|
+
return { url: specifier, shortCircuit: true };
|
|
329
|
+
}
|
|
330
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
331
|
+
const { format: expectedFormat } = runtime;
|
|
332
|
+
if (url.startsWith("file://")) {
|
|
333
|
+
const filename = fileURLToPath(url);
|
|
334
|
+
const match = pickPlugin(filename, runtime);
|
|
335
|
+
if (runtime.loaderConfig.debug) {
|
|
336
|
+
console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
|
|
337
|
+
}
|
|
338
|
+
if (match) {
|
|
339
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
340
|
+
const result = applyPlugin(source, filename, runtime);
|
|
341
|
+
const fallbackFormat = inferFormat(filename, expectedFormat);
|
|
342
|
+
return {
|
|
343
|
+
format: toNodeLoaderFormat(result.format || fallbackFormat),
|
|
344
|
+
source: result.code,
|
|
345
|
+
shortCircuit: true
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (!next) {
|
|
350
|
+
throw new Error("No default loader available for " + url);
|
|
351
|
+
}
|
|
352
|
+
const forwarded = await next(url, context);
|
|
353
|
+
if (forwarded) return forwarded;
|
|
354
|
+
throw new Error("Loader did not return a result for " + url);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export {
|
|
358
|
+
loadHirariConfig,
|
|
359
|
+
IMPORT_META_URL_VARIABLE,
|
|
360
|
+
BYPASS_FLAG,
|
|
361
|
+
BYPASS_PREFIX,
|
|
362
|
+
resolvePlugins,
|
|
363
|
+
createRuntime,
|
|
364
|
+
registerRequireHooks,
|
|
365
|
+
loaderResolve,
|
|
366
|
+
loaderLoad
|
|
367
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-HIW3PA5X.js";
|
|
5
|
+
|
|
6
|
+
// src/register.ts
|
|
7
|
+
function register(cwd = process.cwd()) {
|
|
8
|
+
const runtime = createRuntime(cwd);
|
|
9
|
+
const unregister = registerRequireHooks(runtime);
|
|
10
|
+
return { unregister };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
register
|
|
15
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
BYPASS_FLAG: () => BYPASS_FLAG,
|
|
34
|
+
BYPASS_PREFIX: () => BYPASS_PREFIX,
|
|
34
35
|
IMPORT_META_URL_VARIABLE: () => IMPORT_META_URL_VARIABLE,
|
|
35
36
|
createRuntime: () => createRuntime,
|
|
36
37
|
loadHirariConfig: () => loadHirariConfig,
|
|
@@ -84,6 +85,7 @@ var sourceMapSupport = __toESM(require("source-map-support"), 1);
|
|
|
84
85
|
// src/constants.ts
|
|
85
86
|
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
86
87
|
var BYPASS_FLAG = "__hirari_loader_bypass__";
|
|
88
|
+
var BYPASS_PREFIX = "hirari-bypass:";
|
|
87
89
|
|
|
88
90
|
// src/plugin-manager.ts
|
|
89
91
|
var import_child_process = require("child_process");
|
|
@@ -271,6 +273,7 @@ function register(cwd = process.cwd()) {
|
|
|
271
273
|
// Annotate the CommonJS export names for ESM import in node:
|
|
272
274
|
0 && (module.exports = {
|
|
273
275
|
BYPASS_FLAG,
|
|
276
|
+
BYPASS_PREFIX,
|
|
274
277
|
IMPORT_META_URL_VARIABLE,
|
|
275
278
|
createRuntime,
|
|
276
279
|
loadHirariConfig,
|
package/dist/index.d.cts
CHANGED
|
@@ -25,6 +25,14 @@ interface LoaderPlugin {
|
|
|
25
25
|
* Match is called with the absolute filename. Return true when the plugin should run.
|
|
26
26
|
*/
|
|
27
27
|
match: (filename: string) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Optional resolve hook. Return a URL (or null to skip) to short-circuit resolution.
|
|
30
|
+
*/
|
|
31
|
+
resolve?: (specifier: string, importer: string | null, ctx: LoaderPluginContext) => {
|
|
32
|
+
url: string;
|
|
33
|
+
format?: ModuleFormat;
|
|
34
|
+
shortCircuit?: boolean;
|
|
35
|
+
} | null;
|
|
28
36
|
/**
|
|
29
37
|
* Synchronous transform hook. Should return already-transformed JS.
|
|
30
38
|
*/
|
|
@@ -63,5 +71,6 @@ declare function createRuntime(cwd?: string): RuntimeContext;
|
|
|
63
71
|
|
|
64
72
|
declare const IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
65
73
|
declare const BYPASS_FLAG = "__hirari_loader_bypass__";
|
|
74
|
+
declare const BYPASS_PREFIX = "hirari-bypass:";
|
|
66
75
|
|
|
67
|
-
export { BYPASS_FLAG, type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
|
|
76
|
+
export { BYPASS_FLAG, BYPASS_PREFIX, type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,14 @@ interface LoaderPlugin {
|
|
|
25
25
|
* Match is called with the absolute filename. Return true when the plugin should run.
|
|
26
26
|
*/
|
|
27
27
|
match: (filename: string) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Optional resolve hook. Return a URL (or null to skip) to short-circuit resolution.
|
|
30
|
+
*/
|
|
31
|
+
resolve?: (specifier: string, importer: string | null, ctx: LoaderPluginContext) => {
|
|
32
|
+
url: string;
|
|
33
|
+
format?: ModuleFormat;
|
|
34
|
+
shortCircuit?: boolean;
|
|
35
|
+
} | null;
|
|
28
36
|
/**
|
|
29
37
|
* Synchronous transform hook. Should return already-transformed JS.
|
|
30
38
|
*/
|
|
@@ -63,5 +71,6 @@ declare function createRuntime(cwd?: string): RuntimeContext;
|
|
|
63
71
|
|
|
64
72
|
declare const IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
65
73
|
declare const BYPASS_FLAG = "__hirari_loader_bypass__";
|
|
74
|
+
declare const BYPASS_PREFIX = "hirari-bypass:";
|
|
66
75
|
|
|
67
|
-
export { BYPASS_FLAG, type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
|
|
76
|
+
export { BYPASS_FLAG, BYPASS_PREFIX, type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
register
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VGNNMSLY.js";
|
|
4
4
|
import {
|
|
5
5
|
BYPASS_FLAG,
|
|
6
|
+
BYPASS_PREFIX,
|
|
6
7
|
IMPORT_META_URL_VARIABLE,
|
|
7
8
|
createRuntime,
|
|
8
9
|
loadHirariConfig,
|
|
9
10
|
resolvePlugins
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-HIW3PA5X.js";
|
|
11
12
|
export {
|
|
12
13
|
BYPASS_FLAG,
|
|
14
|
+
BYPASS_PREFIX,
|
|
13
15
|
IMPORT_META_URL_VARIABLE,
|
|
14
16
|
createRuntime,
|
|
15
17
|
loadHirariConfig,
|
package/dist/loader.cjs
CHANGED
|
@@ -42,6 +42,9 @@ var import_url = require("url");
|
|
|
42
42
|
var import_pirates = require("pirates");
|
|
43
43
|
var sourceMapSupport = __toESM(require("source-map-support"), 1);
|
|
44
44
|
|
|
45
|
+
// src/constants.ts
|
|
46
|
+
var BYPASS_PREFIX = "hirari-bypass:";
|
|
47
|
+
|
|
45
48
|
// src/config.ts
|
|
46
49
|
var import_fs = __toESM(require("fs"), 1);
|
|
47
50
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -144,6 +147,7 @@ function resolvePlugins(config, cwd) {
|
|
|
144
147
|
|
|
145
148
|
// src/runtime.ts
|
|
146
149
|
var map = {};
|
|
150
|
+
var packageTypeCache = /* @__PURE__ */ new Map();
|
|
147
151
|
var EXTENSION_CANDIDATES = [
|
|
148
152
|
".ts",
|
|
149
153
|
".mts",
|
|
@@ -168,6 +172,39 @@ function installSourceMaps() {
|
|
|
168
172
|
});
|
|
169
173
|
}
|
|
170
174
|
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
175
|
+
function findNearestPackageType(filename) {
|
|
176
|
+
const dir = import_path3.default.dirname(filename);
|
|
177
|
+
if (packageTypeCache.has(dir)) return packageTypeCache.get(dir);
|
|
178
|
+
let current = dir;
|
|
179
|
+
while (true) {
|
|
180
|
+
const candidate = import_path3.default.join(current, "package.json");
|
|
181
|
+
if (import_fs3.default.existsSync(candidate)) {
|
|
182
|
+
try {
|
|
183
|
+
const pkg = JSON.parse(import_fs3.default.readFileSync(candidate, "utf8"));
|
|
184
|
+
const type = pkg && pkg.type === "module" ? "module" : "commonjs";
|
|
185
|
+
packageTypeCache.set(dir, type);
|
|
186
|
+
return type;
|
|
187
|
+
} catch {
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const parent = import_path3.default.dirname(current);
|
|
192
|
+
if (parent === current) break;
|
|
193
|
+
current = parent;
|
|
194
|
+
}
|
|
195
|
+
packageTypeCache.set(dir, "commonjs");
|
|
196
|
+
return "commonjs";
|
|
197
|
+
}
|
|
198
|
+
function inferFormat(filename, fallback) {
|
|
199
|
+
const ext = import_path3.default.extname(filename);
|
|
200
|
+
if (ext === ".mjs" || ext === ".mts" || ext === ".mtsx") return "esm";
|
|
201
|
+
if (ext === ".cjs" || ext === ".cts") return "cjs";
|
|
202
|
+
if (ext === ".js" || ext === ".ts" || ext === ".tsx" || ext === ".jsx" || ext === ".vue") {
|
|
203
|
+
const pkgType = findNearestPackageType(filename);
|
|
204
|
+
return pkgType === "module" ? "esm" : "cjs";
|
|
205
|
+
}
|
|
206
|
+
return fallback;
|
|
207
|
+
}
|
|
171
208
|
function createRuntime(cwd = process.cwd()) {
|
|
172
209
|
const loaderConfig = loadHirariConfig(cwd);
|
|
173
210
|
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
@@ -227,6 +264,25 @@ function pickPlugin(filename, runtime2) {
|
|
|
227
264
|
async function loaderResolve(specifier, context, next, runtime2) {
|
|
228
265
|
const parentUrl = context && context.parentURL;
|
|
229
266
|
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? import_path3.default.dirname((0, import_url.fileURLToPath)(parentUrl)) : process.cwd();
|
|
267
|
+
if (specifier.startsWith(BYPASS_PREFIX)) {
|
|
268
|
+
const target = specifier.slice(BYPASS_PREFIX.length);
|
|
269
|
+
const url = target.startsWith("file:") ? target : (0, import_url.pathToFileURL)(target).href;
|
|
270
|
+
return { url, shortCircuit: true };
|
|
271
|
+
}
|
|
272
|
+
for (const match of runtime2.resolvedPlugins) {
|
|
273
|
+
if (typeof match.plugin.resolve !== "function") continue;
|
|
274
|
+
const importer = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? (0, import_url.fileURLToPath)(parentUrl) : null;
|
|
275
|
+
const ctx = {
|
|
276
|
+
format: runtime2.format,
|
|
277
|
+
loaderConfig: runtime2.loaderConfig,
|
|
278
|
+
pluginOptions: match.options
|
|
279
|
+
};
|
|
280
|
+
const res = match.plugin.resolve(specifier, importer, ctx);
|
|
281
|
+
if (res && res.url) {
|
|
282
|
+
const url = res.url.startsWith("file:") ? res.url : (0, import_url.pathToFileURL)(res.url).href;
|
|
283
|
+
return { url, shortCircuit: res.shortCircuit !== false, format: res.format };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
230
286
|
const tryResolve = (basePath, note) => {
|
|
231
287
|
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
232
288
|
const candidate = basePath + ext2;
|
|
@@ -274,8 +330,9 @@ async function loaderLoad(url, context, next, runtime2) {
|
|
|
274
330
|
if (match) {
|
|
275
331
|
const source = import_fs3.default.readFileSync(filename, "utf8");
|
|
276
332
|
const result = applyPlugin(source, filename, runtime2);
|
|
333
|
+
const fallbackFormat = inferFormat(filename, expectedFormat);
|
|
277
334
|
return {
|
|
278
|
-
format: toNodeLoaderFormat(result.format ||
|
|
335
|
+
format: toNodeLoaderFormat(result.format || fallbackFormat),
|
|
279
336
|
source: result.code,
|
|
280
337
|
shortCircuit: true
|
|
281
338
|
};
|
package/dist/loader.js
CHANGED
package/dist/register-auto.js
CHANGED
package/dist/register.js
CHANGED