@hirarijs/loader 1.0.3 → 1.0.5
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-FP7GUD2E.js +15 -0
- package/dist/chunk-MCKP6G3Z.js +15 -0
- package/dist/chunk-OFSK6WK7.js +221 -0
- package/dist/chunk-PXA7AW24.js +227 -0
- package/dist/chunk-VFNKWDE2.js +220 -0
- package/dist/chunk-XOMP5MYL.js +15 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/loader.cjs +12 -4
- package/dist/loader.js +1 -1
- package/dist/register-auto.cjs +7 -0
- package/dist/register-auto.js +2 -2
- package/dist/register.cjs +7 -0
- package/dist/register.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-OFSK6WK7.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,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-PXA7AW24.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,221 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: ["@hirarijs/loader-ts", "@hirarijs/loader-tsx", "@hirarijs/loader-vue"]
|
|
7
|
+
};
|
|
8
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
9
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
10
|
+
if (!fs.existsSync(configPath)) {
|
|
11
|
+
return { ...DEFAULT_CONFIG };
|
|
12
|
+
}
|
|
13
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
parsed = JSON.parse(raw);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
19
|
+
}
|
|
20
|
+
const loaderConfig = parsed.loader || {};
|
|
21
|
+
return {
|
|
22
|
+
...DEFAULT_CONFIG,
|
|
23
|
+
...loaderConfig,
|
|
24
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getFormat(config) {
|
|
28
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/constants.ts
|
|
32
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
33
|
+
|
|
34
|
+
// src/plugin-manager.ts
|
|
35
|
+
import { spawnSync } from "child_process";
|
|
36
|
+
import fs2 from "fs";
|
|
37
|
+
import path2 from "path";
|
|
38
|
+
import { createRequire } from "module";
|
|
39
|
+
var PACKAGE_MANAGERS = [
|
|
40
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
41
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
42
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
43
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
44
|
+
];
|
|
45
|
+
function detectPackageManager(cwd) {
|
|
46
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
47
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
48
|
+
}
|
|
49
|
+
return { command: "npm", args: ["install"] };
|
|
50
|
+
}
|
|
51
|
+
function tryRequire(moduleId, cwd) {
|
|
52
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
53
|
+
const loaded = req(moduleId);
|
|
54
|
+
return loaded && (loaded.default || loaded);
|
|
55
|
+
}
|
|
56
|
+
function install(pkg, cwd) {
|
|
57
|
+
const pm = detectPackageManager(cwd);
|
|
58
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
59
|
+
cwd,
|
|
60
|
+
stdio: "inherit",
|
|
61
|
+
env: process.env
|
|
62
|
+
});
|
|
63
|
+
if (result.error) {
|
|
64
|
+
throw result.error;
|
|
65
|
+
}
|
|
66
|
+
if (result.status !== 0) {
|
|
67
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function resolvePlugins(config, cwd) {
|
|
71
|
+
const plugins = [];
|
|
72
|
+
for (const pluginName of config.plugins || []) {
|
|
73
|
+
let loaded = null;
|
|
74
|
+
try {
|
|
75
|
+
loaded = tryRequire(pluginName, cwd);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (config.autoInstall) {
|
|
78
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
79
|
+
install(pluginName, cwd);
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!loaded) continue;
|
|
88
|
+
plugins.push({
|
|
89
|
+
plugin: loaded,
|
|
90
|
+
options: config.pluginOptions?.[pluginName]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return plugins;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/runtime.ts
|
|
97
|
+
import fs3 from "fs";
|
|
98
|
+
import module from "module";
|
|
99
|
+
import { fileURLToPath } from "url";
|
|
100
|
+
import { addHook } from "pirates";
|
|
101
|
+
import * as sourceMapSupport from "source-map-support";
|
|
102
|
+
var map = {};
|
|
103
|
+
function installSourceMaps() {
|
|
104
|
+
sourceMapSupport.install({
|
|
105
|
+
handleUncaughtExceptions: false,
|
|
106
|
+
environment: "node",
|
|
107
|
+
retrieveSourceMap(file) {
|
|
108
|
+
if (map[file]) {
|
|
109
|
+
return { url: file, map: map[file] };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
116
|
+
function createRuntime(cwd = process.cwd()) {
|
|
117
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
118
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
119
|
+
installSourceMaps();
|
|
120
|
+
return {
|
|
121
|
+
cwd,
|
|
122
|
+
loaderConfig,
|
|
123
|
+
resolvedPlugins,
|
|
124
|
+
format: getFormat(loaderConfig)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function pickPlugin(filename, plugins) {
|
|
128
|
+
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
129
|
+
}
|
|
130
|
+
function applyPlugin(code, filename, runtime) {
|
|
131
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
132
|
+
if (!match) return { code };
|
|
133
|
+
const ctx = {
|
|
134
|
+
format: runtime.format,
|
|
135
|
+
loaderConfig: runtime.loaderConfig,
|
|
136
|
+
pluginOptions: match.options
|
|
137
|
+
};
|
|
138
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
139
|
+
if (result.map) {
|
|
140
|
+
map[filename] = result.map;
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function collectExtensions(plugins) {
|
|
145
|
+
const set = /* @__PURE__ */ new Set();
|
|
146
|
+
for (const { plugin } of plugins) {
|
|
147
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
148
|
+
}
|
|
149
|
+
return Array.from(set);
|
|
150
|
+
}
|
|
151
|
+
function registerRequireHooks(runtime) {
|
|
152
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
153
|
+
const compile = (code, filename) => {
|
|
154
|
+
const result = applyPlugin(code, filename, runtime);
|
|
155
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
156
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
157
|
+
return `${banner}${result.code}`;
|
|
158
|
+
}
|
|
159
|
+
return result.code;
|
|
160
|
+
};
|
|
161
|
+
const revert = addHook(compile, {
|
|
162
|
+
exts: extensions,
|
|
163
|
+
ignoreNodeModules: runtime.loaderConfig.hookIgnoreNodeModules ?? true
|
|
164
|
+
});
|
|
165
|
+
const extensionsObj = module.Module._extensions;
|
|
166
|
+
const jsHandler = extensionsObj[".js"];
|
|
167
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
168
|
+
try {
|
|
169
|
+
return jsHandler.call(this, mod, filename);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
172
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
173
|
+
const result = applyPlugin(src, filename, runtime);
|
|
174
|
+
mod._compile(result.code, filename);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return () => {
|
|
181
|
+
revert();
|
|
182
|
+
extensionsObj[".js"] = jsHandler;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
async function loaderResolve(specifier, context, next) {
|
|
186
|
+
if (next) return next(specifier, context, next);
|
|
187
|
+
return { url: specifier };
|
|
188
|
+
}
|
|
189
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
190
|
+
const { format: expectedFormat } = runtime;
|
|
191
|
+
const nodeFormat = toNodeLoaderFormat(expectedFormat);
|
|
192
|
+
if (url.startsWith("file://")) {
|
|
193
|
+
const filename = fileURLToPath(url);
|
|
194
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
195
|
+
if (match) {
|
|
196
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
197
|
+
const result = applyPlugin(source, filename, runtime);
|
|
198
|
+
return {
|
|
199
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
200
|
+
source: result.code,
|
|
201
|
+
shortCircuit: true
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (!next) {
|
|
206
|
+
throw new Error("No default loader available for " + url);
|
|
207
|
+
}
|
|
208
|
+
const forwarded = await next(url, context, next);
|
|
209
|
+
if (forwarded) return forwarded;
|
|
210
|
+
throw new Error("Loader did not return a result for " + url);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export {
|
|
214
|
+
loadHirariConfig,
|
|
215
|
+
IMPORT_META_URL_VARIABLE,
|
|
216
|
+
resolvePlugins,
|
|
217
|
+
createRuntime,
|
|
218
|
+
registerRequireHooks,
|
|
219
|
+
loaderResolve,
|
|
220
|
+
loaderLoad
|
|
221
|
+
};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: ["@hirarijs/loader-ts", "@hirarijs/loader-tsx", "@hirarijs/loader-vue"]
|
|
7
|
+
};
|
|
8
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
9
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
10
|
+
if (!fs.existsSync(configPath)) {
|
|
11
|
+
return { ...DEFAULT_CONFIG };
|
|
12
|
+
}
|
|
13
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
parsed = JSON.parse(raw);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
19
|
+
}
|
|
20
|
+
const loaderConfig = parsed.loader || {};
|
|
21
|
+
return {
|
|
22
|
+
...DEFAULT_CONFIG,
|
|
23
|
+
...loaderConfig,
|
|
24
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getFormat(config) {
|
|
28
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/constants.ts
|
|
32
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
33
|
+
|
|
34
|
+
// src/plugin-manager.ts
|
|
35
|
+
import { spawnSync } from "child_process";
|
|
36
|
+
import fs2 from "fs";
|
|
37
|
+
import path2 from "path";
|
|
38
|
+
import { createRequire } from "module";
|
|
39
|
+
var PACKAGE_MANAGERS = [
|
|
40
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
41
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
42
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
43
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
44
|
+
];
|
|
45
|
+
function detectPackageManager(cwd) {
|
|
46
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
47
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
48
|
+
}
|
|
49
|
+
return { command: "npm", args: ["install"] };
|
|
50
|
+
}
|
|
51
|
+
function tryRequire(moduleId, cwd) {
|
|
52
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
53
|
+
const loaded = req(moduleId);
|
|
54
|
+
return loaded && (loaded.default || loaded);
|
|
55
|
+
}
|
|
56
|
+
function install(pkg, cwd) {
|
|
57
|
+
const pm = detectPackageManager(cwd);
|
|
58
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
59
|
+
cwd,
|
|
60
|
+
stdio: "inherit",
|
|
61
|
+
env: process.env
|
|
62
|
+
});
|
|
63
|
+
if (result.error) {
|
|
64
|
+
throw result.error;
|
|
65
|
+
}
|
|
66
|
+
if (result.status !== 0) {
|
|
67
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function resolvePlugins(config, cwd) {
|
|
71
|
+
const plugins = [];
|
|
72
|
+
for (const pluginName of config.plugins || []) {
|
|
73
|
+
let loaded = null;
|
|
74
|
+
try {
|
|
75
|
+
loaded = tryRequire(pluginName, cwd);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (config.autoInstall) {
|
|
78
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
79
|
+
install(pluginName, cwd);
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!loaded) continue;
|
|
88
|
+
plugins.push({
|
|
89
|
+
plugin: loaded,
|
|
90
|
+
options: config.pluginOptions?.[pluginName]
|
|
91
|
+
});
|
|
92
|
+
if (config.debug) {
|
|
93
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return plugins;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/runtime.ts
|
|
100
|
+
import fs3 from "fs";
|
|
101
|
+
import module from "module";
|
|
102
|
+
import { fileURLToPath } from "url";
|
|
103
|
+
import { addHook } from "pirates";
|
|
104
|
+
import * as sourceMapSupport from "source-map-support";
|
|
105
|
+
var map = {};
|
|
106
|
+
function installSourceMaps() {
|
|
107
|
+
sourceMapSupport.install({
|
|
108
|
+
handleUncaughtExceptions: false,
|
|
109
|
+
environment: "node",
|
|
110
|
+
retrieveSourceMap(file) {
|
|
111
|
+
if (map[file]) {
|
|
112
|
+
return { url: file, map: map[file] };
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
119
|
+
function createRuntime(cwd = process.cwd()) {
|
|
120
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
121
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
122
|
+
installSourceMaps();
|
|
123
|
+
return {
|
|
124
|
+
cwd,
|
|
125
|
+
loaderConfig,
|
|
126
|
+
resolvedPlugins,
|
|
127
|
+
format: getFormat(loaderConfig)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function pickPlugin(filename, plugins) {
|
|
131
|
+
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
132
|
+
}
|
|
133
|
+
function applyPlugin(code, filename, runtime) {
|
|
134
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
135
|
+
if (!match) return { code };
|
|
136
|
+
const ctx = {
|
|
137
|
+
format: runtime.format,
|
|
138
|
+
loaderConfig: runtime.loaderConfig,
|
|
139
|
+
pluginOptions: match.options
|
|
140
|
+
};
|
|
141
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
142
|
+
if (runtime.loaderConfig.debug) {
|
|
143
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
144
|
+
console.log(result.code);
|
|
145
|
+
}
|
|
146
|
+
if (result.map) {
|
|
147
|
+
map[filename] = result.map;
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
function collectExtensions(plugins) {
|
|
152
|
+
const set = /* @__PURE__ */ new Set();
|
|
153
|
+
for (const { plugin } of plugins) {
|
|
154
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
155
|
+
}
|
|
156
|
+
return Array.from(set);
|
|
157
|
+
}
|
|
158
|
+
function registerRequireHooks(runtime) {
|
|
159
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
160
|
+
const compile = (code, filename) => {
|
|
161
|
+
const result = applyPlugin(code, filename, runtime);
|
|
162
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
163
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
164
|
+
return `${banner}${result.code}`;
|
|
165
|
+
}
|
|
166
|
+
return result.code;
|
|
167
|
+
};
|
|
168
|
+
const revert = addHook(compile, {
|
|
169
|
+
exts: extensions,
|
|
170
|
+
ignoreNodeModules: runtime.loaderConfig.hookIgnoreNodeModules ?? true
|
|
171
|
+
});
|
|
172
|
+
const extensionsObj = module.Module._extensions;
|
|
173
|
+
const jsHandler = extensionsObj[".js"];
|
|
174
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
175
|
+
try {
|
|
176
|
+
return jsHandler.call(this, mod, filename);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
179
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
180
|
+
const result = applyPlugin(src, filename, runtime);
|
|
181
|
+
mod._compile(result.code, filename);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
return () => {
|
|
188
|
+
revert();
|
|
189
|
+
extensionsObj[".js"] = jsHandler;
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async function loaderResolve(specifier, context, next) {
|
|
193
|
+
if (next) return next(specifier, context, next);
|
|
194
|
+
return { url: specifier };
|
|
195
|
+
}
|
|
196
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
197
|
+
const { format: expectedFormat } = runtime;
|
|
198
|
+
if (url.startsWith("file://")) {
|
|
199
|
+
const filename = fileURLToPath(url);
|
|
200
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
201
|
+
if (match) {
|
|
202
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
203
|
+
const result = applyPlugin(source, filename, runtime);
|
|
204
|
+
return {
|
|
205
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
206
|
+
source: result.code,
|
|
207
|
+
shortCircuit: true
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (!next) {
|
|
212
|
+
throw new Error("No default loader available for " + url);
|
|
213
|
+
}
|
|
214
|
+
const forwarded = await next(url, context);
|
|
215
|
+
if (forwarded) return forwarded;
|
|
216
|
+
throw new Error("Loader did not return a result for " + url);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export {
|
|
220
|
+
loadHirariConfig,
|
|
221
|
+
IMPORT_META_URL_VARIABLE,
|
|
222
|
+
resolvePlugins,
|
|
223
|
+
createRuntime,
|
|
224
|
+
registerRequireHooks,
|
|
225
|
+
loaderResolve,
|
|
226
|
+
loaderLoad
|
|
227
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: ["@hirarijs/loader-ts", "@hirarijs/loader-tsx", "@hirarijs/loader-vue"]
|
|
7
|
+
};
|
|
8
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
9
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
10
|
+
if (!fs.existsSync(configPath)) {
|
|
11
|
+
return { ...DEFAULT_CONFIG };
|
|
12
|
+
}
|
|
13
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
parsed = JSON.parse(raw);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
19
|
+
}
|
|
20
|
+
const loaderConfig = parsed.loader || {};
|
|
21
|
+
return {
|
|
22
|
+
...DEFAULT_CONFIG,
|
|
23
|
+
...loaderConfig,
|
|
24
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getFormat(config) {
|
|
28
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/constants.ts
|
|
32
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
33
|
+
|
|
34
|
+
// src/plugin-manager.ts
|
|
35
|
+
import { spawnSync } from "child_process";
|
|
36
|
+
import fs2 from "fs";
|
|
37
|
+
import path2 from "path";
|
|
38
|
+
import { createRequire } from "module";
|
|
39
|
+
var PACKAGE_MANAGERS = [
|
|
40
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
41
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
42
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
43
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
44
|
+
];
|
|
45
|
+
function detectPackageManager(cwd) {
|
|
46
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
47
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
48
|
+
}
|
|
49
|
+
return { command: "npm", args: ["install"] };
|
|
50
|
+
}
|
|
51
|
+
function tryRequire(moduleId, cwd) {
|
|
52
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
53
|
+
const loaded = req(moduleId);
|
|
54
|
+
return loaded && (loaded.default || loaded);
|
|
55
|
+
}
|
|
56
|
+
function install(pkg, cwd) {
|
|
57
|
+
const pm = detectPackageManager(cwd);
|
|
58
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
59
|
+
cwd,
|
|
60
|
+
stdio: "inherit",
|
|
61
|
+
env: process.env
|
|
62
|
+
});
|
|
63
|
+
if (result.error) {
|
|
64
|
+
throw result.error;
|
|
65
|
+
}
|
|
66
|
+
if (result.status !== 0) {
|
|
67
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function resolvePlugins(config, cwd) {
|
|
71
|
+
const plugins = [];
|
|
72
|
+
for (const pluginName of config.plugins || []) {
|
|
73
|
+
let loaded = null;
|
|
74
|
+
try {
|
|
75
|
+
loaded = tryRequire(pluginName, cwd);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (config.autoInstall) {
|
|
78
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
79
|
+
install(pluginName, cwd);
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!loaded) continue;
|
|
88
|
+
plugins.push({
|
|
89
|
+
plugin: loaded,
|
|
90
|
+
options: config.pluginOptions?.[pluginName]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return plugins;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/runtime.ts
|
|
97
|
+
import fs3 from "fs";
|
|
98
|
+
import module from "module";
|
|
99
|
+
import { fileURLToPath } from "url";
|
|
100
|
+
import { addHook } from "pirates";
|
|
101
|
+
import * as sourceMapSupport from "source-map-support";
|
|
102
|
+
var map = {};
|
|
103
|
+
function installSourceMaps() {
|
|
104
|
+
sourceMapSupport.install({
|
|
105
|
+
handleUncaughtExceptions: false,
|
|
106
|
+
environment: "node",
|
|
107
|
+
retrieveSourceMap(file) {
|
|
108
|
+
if (map[file]) {
|
|
109
|
+
return { url: file, map: map[file] };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
116
|
+
function createRuntime(cwd = process.cwd()) {
|
|
117
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
118
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
119
|
+
installSourceMaps();
|
|
120
|
+
return {
|
|
121
|
+
cwd,
|
|
122
|
+
loaderConfig,
|
|
123
|
+
resolvedPlugins,
|
|
124
|
+
format: getFormat(loaderConfig)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function pickPlugin(filename, plugins) {
|
|
128
|
+
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
129
|
+
}
|
|
130
|
+
function applyPlugin(code, filename, runtime) {
|
|
131
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
132
|
+
if (!match) return { code };
|
|
133
|
+
const ctx = {
|
|
134
|
+
format: runtime.format,
|
|
135
|
+
loaderConfig: runtime.loaderConfig,
|
|
136
|
+
pluginOptions: match.options
|
|
137
|
+
};
|
|
138
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
139
|
+
if (result.map) {
|
|
140
|
+
map[filename] = result.map;
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function collectExtensions(plugins) {
|
|
145
|
+
const set = /* @__PURE__ */ new Set();
|
|
146
|
+
for (const { plugin } of plugins) {
|
|
147
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
148
|
+
}
|
|
149
|
+
return Array.from(set);
|
|
150
|
+
}
|
|
151
|
+
function registerRequireHooks(runtime) {
|
|
152
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
153
|
+
const compile = (code, filename) => {
|
|
154
|
+
const result = applyPlugin(code, filename, runtime);
|
|
155
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
156
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
157
|
+
return `${banner}${result.code}`;
|
|
158
|
+
}
|
|
159
|
+
return result.code;
|
|
160
|
+
};
|
|
161
|
+
const revert = addHook(compile, {
|
|
162
|
+
exts: extensions,
|
|
163
|
+
ignoreNodeModules: runtime.loaderConfig.hookIgnoreNodeModules ?? true
|
|
164
|
+
});
|
|
165
|
+
const extensionsObj = module.Module._extensions;
|
|
166
|
+
const jsHandler = extensionsObj[".js"];
|
|
167
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
168
|
+
try {
|
|
169
|
+
return jsHandler.call(this, mod, filename);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
172
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
173
|
+
const result = applyPlugin(src, filename, runtime);
|
|
174
|
+
mod._compile(result.code, filename);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return () => {
|
|
181
|
+
revert();
|
|
182
|
+
extensionsObj[".js"] = jsHandler;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
async function loaderResolve(specifier, context, next) {
|
|
186
|
+
if (next) return next(specifier, context, next);
|
|
187
|
+
return { url: specifier };
|
|
188
|
+
}
|
|
189
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
190
|
+
const { format: expectedFormat } = runtime;
|
|
191
|
+
if (url.startsWith("file://")) {
|
|
192
|
+
const filename = fileURLToPath(url);
|
|
193
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
194
|
+
if (match) {
|
|
195
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
196
|
+
const result = applyPlugin(source, filename, runtime);
|
|
197
|
+
return {
|
|
198
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
199
|
+
source: result.code,
|
|
200
|
+
shortCircuit: true
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (!next) {
|
|
205
|
+
throw new Error("No default loader available for " + url);
|
|
206
|
+
}
|
|
207
|
+
const forwarded = await next(url, context);
|
|
208
|
+
if (forwarded) return forwarded;
|
|
209
|
+
throw new Error("Loader did not return a result for " + url);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export {
|
|
213
|
+
loadHirariConfig,
|
|
214
|
+
IMPORT_META_URL_VARIABLE,
|
|
215
|
+
resolvePlugins,
|
|
216
|
+
createRuntime,
|
|
217
|
+
registerRequireHooks,
|
|
218
|
+
loaderResolve,
|
|
219
|
+
loaderLoad
|
|
220
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-VFNKWDE2.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
|
@@ -136,6 +136,9 @@ function resolvePlugins(config, cwd) {
|
|
|
136
136
|
plugin: loaded,
|
|
137
137
|
options: config.pluginOptions?.[pluginName]
|
|
138
138
|
});
|
|
139
|
+
if (config.debug) {
|
|
140
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
141
|
+
}
|
|
139
142
|
}
|
|
140
143
|
return plugins;
|
|
141
144
|
}
|
|
@@ -177,6 +180,10 @@ function applyPlugin(code, filename, runtime) {
|
|
|
177
180
|
pluginOptions: match.options
|
|
178
181
|
};
|
|
179
182
|
const result = match.plugin.transform(code, filename, ctx);
|
|
183
|
+
if (runtime.loaderConfig.debug) {
|
|
184
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
185
|
+
console.log(result.code);
|
|
186
|
+
}
|
|
180
187
|
if (result.map) {
|
|
181
188
|
map[filename] = result.map;
|
|
182
189
|
}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
register
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MCKP6G3Z.js";
|
|
4
4
|
import {
|
|
5
5
|
IMPORT_META_URL_VARIABLE,
|
|
6
6
|
createRuntime,
|
|
7
7
|
loadHirariConfig,
|
|
8
8
|
resolvePlugins
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PXA7AW24.js";
|
|
10
10
|
export {
|
|
11
11
|
IMPORT_META_URL_VARIABLE,
|
|
12
12
|
createRuntime,
|
package/dist/loader.cjs
CHANGED
|
@@ -129,6 +129,9 @@ function resolvePlugins(config, cwd) {
|
|
|
129
129
|
plugin: loaded,
|
|
130
130
|
options: config.pluginOptions?.[pluginName]
|
|
131
131
|
});
|
|
132
|
+
if (config.debug) {
|
|
133
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
134
|
+
}
|
|
132
135
|
}
|
|
133
136
|
return plugins;
|
|
134
137
|
}
|
|
@@ -171,6 +174,10 @@ function applyPlugin(code, filename, runtime2) {
|
|
|
171
174
|
pluginOptions: match.options
|
|
172
175
|
};
|
|
173
176
|
const result = match.plugin.transform(code, filename, ctx);
|
|
177
|
+
if (runtime2.loaderConfig.debug) {
|
|
178
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
179
|
+
console.log(result.code);
|
|
180
|
+
}
|
|
174
181
|
if (result.map) {
|
|
175
182
|
map[filename] = result.map;
|
|
176
183
|
}
|
|
@@ -182,7 +189,6 @@ async function loaderResolve(specifier, context, next) {
|
|
|
182
189
|
}
|
|
183
190
|
async function loaderLoad(url, context, next, runtime2) {
|
|
184
191
|
const { format: expectedFormat } = runtime2;
|
|
185
|
-
const nodeFormat = toNodeLoaderFormat(expectedFormat);
|
|
186
192
|
if (url.startsWith("file://")) {
|
|
187
193
|
const filename = (0, import_url.fileURLToPath)(url);
|
|
188
194
|
const match = pickPlugin(filename, runtime2.resolvedPlugins);
|
|
@@ -196,10 +202,12 @@ async function loaderLoad(url, context, next, runtime2) {
|
|
|
196
202
|
};
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
|
-
if (next) {
|
|
200
|
-
|
|
205
|
+
if (!next) {
|
|
206
|
+
throw new Error("No default loader available for " + url);
|
|
201
207
|
}
|
|
202
|
-
|
|
208
|
+
const forwarded = await next(url, context);
|
|
209
|
+
if (forwarded) return forwarded;
|
|
210
|
+
throw new Error("Loader did not return a result for " + url);
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
// src/loader.ts
|
package/dist/loader.js
CHANGED
package/dist/register-auto.cjs
CHANGED
|
@@ -119,6 +119,9 @@ function resolvePlugins(config, cwd) {
|
|
|
119
119
|
plugin: loaded,
|
|
120
120
|
options: config.pluginOptions?.[pluginName]
|
|
121
121
|
});
|
|
122
|
+
if (config.debug) {
|
|
123
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
124
|
+
}
|
|
122
125
|
}
|
|
123
126
|
return plugins;
|
|
124
127
|
}
|
|
@@ -160,6 +163,10 @@ function applyPlugin(code, filename, runtime) {
|
|
|
160
163
|
pluginOptions: match.options
|
|
161
164
|
};
|
|
162
165
|
const result = match.plugin.transform(code, filename, ctx);
|
|
166
|
+
if (runtime.loaderConfig.debug) {
|
|
167
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
168
|
+
console.log(result.code);
|
|
169
|
+
}
|
|
163
170
|
if (result.map) {
|
|
164
171
|
map[filename] = result.map;
|
|
165
172
|
}
|
package/dist/register-auto.js
CHANGED
package/dist/register.cjs
CHANGED
|
@@ -131,6 +131,9 @@ function resolvePlugins(config, cwd) {
|
|
|
131
131
|
plugin: loaded,
|
|
132
132
|
options: config.pluginOptions?.[pluginName]
|
|
133
133
|
});
|
|
134
|
+
if (config.debug) {
|
|
135
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
136
|
+
}
|
|
134
137
|
}
|
|
135
138
|
return plugins;
|
|
136
139
|
}
|
|
@@ -172,6 +175,10 @@ function applyPlugin(code, filename, runtime) {
|
|
|
172
175
|
pluginOptions: match.options
|
|
173
176
|
};
|
|
174
177
|
const result = match.plugin.transform(code, filename, ctx);
|
|
178
|
+
if (runtime.loaderConfig.debug) {
|
|
179
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
180
|
+
console.log(result.code);
|
|
181
|
+
}
|
|
175
182
|
if (result.map) {
|
|
176
183
|
map[filename] = result.map;
|
|
177
184
|
}
|
package/dist/register.js
CHANGED