@hirarijs/loader 1.0.12 → 1.0.14

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.
@@ -0,0 +1,15 @@
1
+ import {
2
+ createRuntime,
3
+ registerRequireHooks
4
+ } from "./chunk-ORDKCG7D.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
+ };
@@ -0,0 +1,311 @@
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
+
40
+ // src/plugin-manager.ts
41
+ import { spawnSync } from "child_process";
42
+ import fs2 from "fs";
43
+ import path2 from "path";
44
+ import { createRequire } from "module";
45
+ var PACKAGE_MANAGERS = [
46
+ { lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
47
+ { lock: "yarn.lock", command: "yarn", args: ["add"] },
48
+ { lock: "package-lock.json", command: "npm", args: ["install"] },
49
+ { lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
50
+ ];
51
+ function detectPackageManager(cwd) {
52
+ for (const pm of PACKAGE_MANAGERS) {
53
+ if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
54
+ }
55
+ return { command: "npm", args: ["install"] };
56
+ }
57
+ function tryRequire(moduleId, cwd) {
58
+ const req = createRequire(path2.join(cwd, "noop.js"));
59
+ const loaded = req(moduleId);
60
+ return loaded && (loaded.default || loaded);
61
+ }
62
+ function install(pkg, cwd) {
63
+ const pm = detectPackageManager(cwd);
64
+ const result = spawnSync(pm.command, [...pm.args, pkg], {
65
+ cwd,
66
+ stdio: "inherit",
67
+ env: process.env
68
+ });
69
+ if (result.error) {
70
+ throw result.error;
71
+ }
72
+ if (result.status !== 0) {
73
+ throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
74
+ }
75
+ }
76
+ function resolvePlugins(config, cwd) {
77
+ const plugins = [];
78
+ for (const pluginName of config.plugins || []) {
79
+ let loaded = null;
80
+ try {
81
+ loaded = tryRequire(pluginName, cwd);
82
+ } catch (error) {
83
+ if (config.autoInstall) {
84
+ console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
85
+ install(pluginName, cwd);
86
+ loaded = tryRequire(pluginName, cwd);
87
+ } else {
88
+ throw new Error(
89
+ `Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
90
+ );
91
+ }
92
+ }
93
+ if (!loaded) continue;
94
+ plugins.push({
95
+ plugin: loaded,
96
+ options: config.pluginOptions?.[pluginName]
97
+ });
98
+ if (config.debug) {
99
+ console.log(`[hirari-loader] loaded plugin ${pluginName}`);
100
+ }
101
+ }
102
+ return plugins;
103
+ }
104
+
105
+ // src/runtime.ts
106
+ import fs3 from "fs";
107
+ import module from "module";
108
+ import path3 from "path";
109
+ import { fileURLToPath, pathToFileURL } from "url";
110
+ import { addHook } from "pirates";
111
+ import * as sourceMapSupport from "source-map-support";
112
+ var map = {};
113
+ var EXTENSION_CANDIDATES = [
114
+ ".ts",
115
+ ".mts",
116
+ ".cts",
117
+ ".tsx",
118
+ ".jsx",
119
+ ".vue",
120
+ ".js",
121
+ ".mjs",
122
+ ".cjs"
123
+ ];
124
+ function installSourceMaps() {
125
+ sourceMapSupport.install({
126
+ handleUncaughtExceptions: false,
127
+ environment: "node",
128
+ retrieveSourceMap(file) {
129
+ if (map[file]) {
130
+ return { url: file, map: map[file] };
131
+ }
132
+ return null;
133
+ }
134
+ });
135
+ }
136
+ var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
137
+ function createRuntime(cwd = process.cwd()) {
138
+ const loaderConfig = loadHirariConfig(cwd);
139
+ const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
140
+ installSourceMaps();
141
+ return {
142
+ cwd,
143
+ loaderConfig,
144
+ resolvedPlugins,
145
+ format: getFormat(loaderConfig)
146
+ };
147
+ }
148
+ function applyPlugin(code, filename, runtime) {
149
+ let currentCode = code;
150
+ let currentFormat = runtime.format;
151
+ let lastResult = null;
152
+ for (const match of runtime.resolvedPlugins) {
153
+ if (!match.plugin.match(filename)) continue;
154
+ const ctx = {
155
+ format: currentFormat,
156
+ loaderConfig: runtime.loaderConfig,
157
+ pluginOptions: match.options
158
+ };
159
+ const result = match.plugin.transform(currentCode, filename, ctx);
160
+ if (runtime.loaderConfig.debug) {
161
+ console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
162
+ }
163
+ if (result.map) {
164
+ map[filename] = result.map;
165
+ }
166
+ if (result.format) {
167
+ currentFormat = result.format;
168
+ }
169
+ if (result.continue) {
170
+ lastResult = result;
171
+ if (result.code) {
172
+ currentCode = result.code;
173
+ }
174
+ continue;
175
+ }
176
+ return result;
177
+ }
178
+ if (lastResult) {
179
+ return {
180
+ code: lastResult.code ?? currentCode,
181
+ map: lastResult.map,
182
+ format: lastResult.format ?? currentFormat
183
+ };
184
+ }
185
+ if (runtime.loaderConfig.debug) {
186
+ console.log(`[hirari-loader] no plugin matched ${filename}`);
187
+ }
188
+ return { code: currentCode };
189
+ }
190
+ function pickPlugin(filename, runtime) {
191
+ return runtime.resolvedPlugins.find(({ plugin }) => plugin.match(filename));
192
+ }
193
+ function collectExtensions(plugins) {
194
+ const set = /* @__PURE__ */ new Set();
195
+ for (const { plugin } of plugins) {
196
+ plugin.extensions.forEach((ext) => set.add(ext));
197
+ }
198
+ return Array.from(set);
199
+ }
200
+ function registerRequireHooks(runtime) {
201
+ const extensions = collectExtensions(runtime.resolvedPlugins);
202
+ const compile = (code, filename) => {
203
+ if (globalThis[BYPASS_FLAG]) {
204
+ return code;
205
+ }
206
+ const result = applyPlugin(code, filename, runtime);
207
+ const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
208
+ if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
209
+ return `${banner}${result.code}`;
210
+ }
211
+ return result.code;
212
+ };
213
+ const revert = addHook(compile, {
214
+ exts: extensions,
215
+ ignoreNodeModules: false
216
+ });
217
+ const extensionsObj = module.Module._extensions;
218
+ const jsHandler = extensionsObj[".js"];
219
+ extensionsObj[".js"] = function(mod, filename) {
220
+ try {
221
+ return jsHandler.call(this, mod, filename);
222
+ } catch (error) {
223
+ if (error && error.code === "ERR_REQUIRE_ESM") {
224
+ const src = fs3.readFileSync(filename, "utf8");
225
+ const result = applyPlugin(src, filename, runtime);
226
+ mod._compile(result.code, filename);
227
+ return;
228
+ }
229
+ throw error;
230
+ }
231
+ };
232
+ return () => {
233
+ revert();
234
+ extensionsObj[".js"] = jsHandler;
235
+ };
236
+ }
237
+ async function loaderResolve(specifier, context, next, runtime) {
238
+ const parentUrl = context && context.parentURL;
239
+ const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? path3.dirname(fileURLToPath(parentUrl)) : process.cwd();
240
+ const tryResolve = (basePath, note) => {
241
+ for (const ext2 of EXTENSION_CANDIDATES) {
242
+ const candidate = basePath + ext2;
243
+ if (fs3.existsSync(candidate) && fs3.statSync(candidate).isFile()) {
244
+ const url = pathToFileURL(candidate).href;
245
+ if (runtime.loaderConfig.debug) {
246
+ console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
247
+ }
248
+ return { url, shortCircuit: true };
249
+ }
250
+ const indexCandidate = path3.join(basePath, "index" + ext2);
251
+ if (fs3.existsSync(indexCandidate) && fs3.statSync(indexCandidate).isFile()) {
252
+ const url = pathToFileURL(indexCandidate).href;
253
+ if (runtime.loaderConfig.debug) {
254
+ console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
255
+ }
256
+ return { url, shortCircuit: true };
257
+ }
258
+ }
259
+ return null;
260
+ };
261
+ if (!path3.extname(specifier) && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:")) && !specifier.startsWith("node:")) {
262
+ const basePath = specifier.startsWith("file:") ? fileURLToPath(specifier) : specifier.startsWith("/") ? specifier : path3.resolve(baseDir, specifier);
263
+ const res = tryResolve(basePath, "extless");
264
+ if (res) return res;
265
+ }
266
+ const ext = path3.extname(specifier);
267
+ if ((ext === ".js" || ext === ".mjs" || ext === ".cjs") && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:"))) {
268
+ const withoutExt = specifier.slice(0, -ext.length);
269
+ const basePath = specifier.startsWith("file:") ? fileURLToPath(withoutExt) : specifier.startsWith("/") ? withoutExt : path3.resolve(baseDir, withoutExt);
270
+ const res = tryResolve(basePath, "fallback-js");
271
+ if (res) return res;
272
+ }
273
+ if (next) return next(specifier, context);
274
+ return { url: specifier, shortCircuit: true };
275
+ }
276
+ async function loaderLoad(url, context, next, runtime) {
277
+ const { format: expectedFormat } = runtime;
278
+ if (url.startsWith("file://")) {
279
+ const filename = fileURLToPath(url);
280
+ const match = pickPlugin(filename, runtime);
281
+ if (runtime.loaderConfig.debug) {
282
+ console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
283
+ }
284
+ if (match) {
285
+ const source = fs3.readFileSync(filename, "utf8");
286
+ const result = applyPlugin(source, filename, runtime);
287
+ return {
288
+ format: toNodeLoaderFormat(result.format || expectedFormat),
289
+ source: result.code,
290
+ shortCircuit: true
291
+ };
292
+ }
293
+ }
294
+ if (!next) {
295
+ throw new Error("No default loader available for " + url);
296
+ }
297
+ const forwarded = await next(url, context);
298
+ if (forwarded) return forwarded;
299
+ throw new Error("Loader did not return a result for " + url);
300
+ }
301
+
302
+ export {
303
+ loadHirariConfig,
304
+ IMPORT_META_URL_VARIABLE,
305
+ BYPASS_FLAG,
306
+ resolvePlugins,
307
+ createRuntime,
308
+ registerRequireHooks,
309
+ loaderResolve,
310
+ loaderLoad
311
+ };
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ BYPASS_FLAG: () => BYPASS_FLAG,
33
34
  IMPORT_META_URL_VARIABLE: () => IMPORT_META_URL_VARIABLE,
34
35
  createRuntime: () => createRuntime,
35
36
  loadHirariConfig: () => loadHirariConfig,
@@ -82,6 +83,7 @@ var sourceMapSupport = __toESM(require("source-map-support"), 1);
82
83
 
83
84
  // src/constants.ts
84
85
  var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
86
+ var BYPASS_FLAG = "__hirari_loader_bypass__";
85
87
 
86
88
  // src/plugin-manager.ts
87
89
  var import_child_process = require("child_process");
@@ -225,6 +227,9 @@ function collectExtensions(plugins) {
225
227
  function registerRequireHooks(runtime) {
226
228
  const extensions = collectExtensions(runtime.resolvedPlugins);
227
229
  const compile = (code, filename) => {
230
+ if (globalThis[BYPASS_FLAG]) {
231
+ return code;
232
+ }
228
233
  const result = applyPlugin(code, filename, runtime);
229
234
  const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
230
235
  if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
@@ -265,6 +270,7 @@ function register(cwd = process.cwd()) {
265
270
  }
266
271
  // Annotate the CommonJS export names for ESM import in node:
267
272
  0 && (module.exports = {
273
+ BYPASS_FLAG,
268
274
  IMPORT_META_URL_VARIABLE,
269
275
  createRuntime,
270
276
  loadHirariConfig,
package/dist/index.d.cts CHANGED
@@ -62,5 +62,6 @@ interface RuntimeContext {
62
62
  declare function createRuntime(cwd?: string): RuntimeContext;
63
63
 
64
64
  declare const IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
65
+ declare const BYPASS_FLAG = "__hirari_loader_bypass__";
65
66
 
66
- export { type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
67
+ export { BYPASS_FLAG, 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
@@ -62,5 +62,6 @@ interface RuntimeContext {
62
62
  declare function createRuntime(cwd?: string): RuntimeContext;
63
63
 
64
64
  declare const IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
65
+ declare const BYPASS_FLAG = "__hirari_loader_bypass__";
65
66
 
66
- export { type HirariConfig, IMPORT_META_URL_VARIABLE, type LoaderConfig, type LoaderPlugin, type LoaderPluginContext, type ModuleFormat, type TransformResult, createRuntime, loadHirariConfig, resolvePlugins };
67
+ export { BYPASS_FLAG, 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,13 +1,15 @@
1
1
  import {
2
2
  register
3
- } from "./chunk-7FOXDJEC.js";
3
+ } from "./chunk-B7W66ZEK.js";
4
4
  import {
5
+ BYPASS_FLAG,
5
6
  IMPORT_META_URL_VARIABLE,
6
7
  createRuntime,
7
8
  loadHirariConfig,
8
9
  resolvePlugins
9
- } from "./chunk-BFYLVEVR.js";
10
+ } from "./chunk-ORDKCG7D.js";
10
11
  export {
12
+ BYPASS_FLAG,
11
13
  IMPORT_META_URL_VARIABLE,
12
14
  createRuntime,
13
15
  loadHirariConfig,
package/dist/loader.cjs CHANGED
@@ -235,7 +235,7 @@ async function loaderResolve(specifier, context, next, runtime2) {
235
235
  if (runtime2.loaderConfig.debug) {
236
236
  console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
237
237
  }
238
- return { url };
238
+ return { url, shortCircuit: true };
239
239
  }
240
240
  const indexCandidate = import_path3.default.join(basePath, "index" + ext2);
241
241
  if (import_fs3.default.existsSync(indexCandidate) && import_fs3.default.statSync(indexCandidate).isFile()) {
@@ -243,7 +243,7 @@ async function loaderResolve(specifier, context, next, runtime2) {
243
243
  if (runtime2.loaderConfig.debug) {
244
244
  console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
245
245
  }
246
- return { url };
246
+ return { url, shortCircuit: true };
247
247
  }
248
248
  }
249
249
  return null;
@@ -261,7 +261,7 @@ async function loaderResolve(specifier, context, next, runtime2) {
261
261
  if (res) return res;
262
262
  }
263
263
  if (next) return next(specifier, context);
264
- return { url: specifier };
264
+ return { url: specifier, shortCircuit: true };
265
265
  }
266
266
  async function loaderLoad(url, context, next, runtime2) {
267
267
  const { format: expectedFormat } = runtime2;
package/dist/loader.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  createRuntime,
3
3
  loaderLoad,
4
4
  loaderResolve
5
- } from "./chunk-BFYLVEVR.js";
5
+ } from "./chunk-ORDKCG7D.js";
6
6
 
7
7
  // src/loader.ts
8
8
  var runtime = createRuntime();
@@ -30,6 +30,7 @@ var sourceMapSupport = __toESM(require("source-map-support"), 1);
30
30
 
31
31
  // src/constants.ts
32
32
  var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
33
+ var BYPASS_FLAG = "__hirari_loader_bypass__";
33
34
 
34
35
  // src/config.ts
35
36
  var import_fs = __toESM(require("fs"), 1);
@@ -208,6 +209,9 @@ function collectExtensions(plugins) {
208
209
  function registerRequireHooks(runtime) {
209
210
  const extensions = collectExtensions(runtime.resolvedPlugins);
210
211
  const compile = (code, filename) => {
212
+ if (globalThis[BYPASS_FLAG]) {
213
+ return code;
214
+ }
211
215
  const result = applyPlugin(code, filename, runtime);
212
216
  const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
213
217
  if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  register
3
- } from "./chunk-7FOXDJEC.js";
4
- import "./chunk-BFYLVEVR.js";
3
+ } from "./chunk-B7W66ZEK.js";
4
+ import "./chunk-ORDKCG7D.js";
5
5
 
6
6
  // src/register-auto.ts
7
7
  register();
package/dist/register.cjs CHANGED
@@ -42,6 +42,7 @@ var sourceMapSupport = __toESM(require("source-map-support"), 1);
42
42
 
43
43
  // src/constants.ts
44
44
  var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
45
+ var BYPASS_FLAG = "__hirari_loader_bypass__";
45
46
 
46
47
  // src/config.ts
47
48
  var import_fs = __toESM(require("fs"), 1);
@@ -220,6 +221,9 @@ function collectExtensions(plugins) {
220
221
  function registerRequireHooks(runtime) {
221
222
  const extensions = collectExtensions(runtime.resolvedPlugins);
222
223
  const compile = (code, filename) => {
224
+ if (globalThis[BYPASS_FLAG]) {
225
+ return code;
226
+ }
223
227
  const result = applyPlugin(code, filename, runtime);
224
228
  const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
225
229
  if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
package/dist/register.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  register
3
- } from "./chunk-7FOXDJEC.js";
4
- import "./chunk-BFYLVEVR.js";
3
+ } from "./chunk-B7W66ZEK.js";
4
+ import "./chunk-ORDKCG7D.js";
5
5
  export {
6
6
  register
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hirarijs/loader",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Runtime loader for HirariJS that wires loader plugins and config",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",