fortiplugin-bundle-adapter 0.0.1 → 0.0.3
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/index.cjs +165 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.mjs +164 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
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
|
default: () => prep,
|
|
34
|
+
discoverEntrypoints: () => generatePluginInputs,
|
|
34
35
|
fortiPrepTransform: () => fortiPrepTransform
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -92,12 +93,12 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
92
93
|
return {
|
|
93
94
|
name: "fortiplugin-prep/transform",
|
|
94
95
|
visitor: {
|
|
95
|
-
ImportDeclaration(
|
|
96
|
-
const node =
|
|
96
|
+
ImportDeclaration(path2) {
|
|
97
|
+
const node = path2.node;
|
|
97
98
|
const importId = node.source.value;
|
|
98
99
|
if (!shouldInject(importId, opts)) {
|
|
99
100
|
keptImports.push(node);
|
|
100
|
-
|
|
101
|
+
path2.remove();
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
for (const s of node.specifiers) {
|
|
@@ -113,23 +114,23 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
|
-
|
|
117
|
+
path2.remove();
|
|
117
118
|
},
|
|
118
|
-
ExportDefaultDeclaration(
|
|
119
|
-
const decl =
|
|
119
|
+
ExportDefaultDeclaration(path2) {
|
|
120
|
+
const decl = path2.node.declaration;
|
|
120
121
|
if (t.isIdentifier(decl)) {
|
|
121
122
|
defaultExportLocalName = decl.name;
|
|
122
|
-
|
|
123
|
+
path2.remove();
|
|
123
124
|
return;
|
|
124
125
|
}
|
|
125
|
-
const id =
|
|
126
|
-
|
|
126
|
+
const id = path2.scope.generateUidIdentifier("defaultExport");
|
|
127
|
+
path2.replaceWith(
|
|
127
128
|
t.variableDeclaration("const", [t.variableDeclarator(id, decl)])
|
|
128
129
|
);
|
|
129
130
|
defaultExportLocalName = id.name;
|
|
130
131
|
},
|
|
131
|
-
ExportNamedDeclaration(
|
|
132
|
-
const node =
|
|
132
|
+
ExportNamedDeclaration(path2) {
|
|
133
|
+
const node = path2.node;
|
|
133
134
|
keptNamedExports.push(node);
|
|
134
135
|
if (node.specifiers?.length) {
|
|
135
136
|
let foundExplicitDefault = false;
|
|
@@ -152,13 +153,13 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
path2.remove();
|
|
156
157
|
},
|
|
157
158
|
Program: {
|
|
158
|
-
exit(
|
|
159
|
-
const program =
|
|
159
|
+
exit(path2) {
|
|
160
|
+
const program = path2.node;
|
|
160
161
|
if (!defaultExportLocalName) {
|
|
161
|
-
throw
|
|
162
|
+
throw path2.buildCodeFrameError(DEFAULT_EXPORT_ERROR);
|
|
162
163
|
}
|
|
163
164
|
const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);
|
|
164
165
|
const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;
|
|
@@ -339,8 +340,157 @@ function prep(options = {}) {
|
|
|
339
340
|
}
|
|
340
341
|
};
|
|
341
342
|
}
|
|
343
|
+
|
|
344
|
+
// src/utils/generate-plugin-inputs.ts
|
|
345
|
+
var import_node_path2 = __toESM(require("path"));
|
|
346
|
+
var fs = __toESM(require("fs"));
|
|
347
|
+
var EXT_PATTERN = /\.(tsx?|jsx?)$/i;
|
|
348
|
+
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
349
|
+
"node_modules",
|
|
350
|
+
".git",
|
|
351
|
+
".vite",
|
|
352
|
+
".internal",
|
|
353
|
+
"dist",
|
|
354
|
+
"build",
|
|
355
|
+
"public"
|
|
356
|
+
]);
|
|
357
|
+
var DEFAULT_COMPONENT_LIKE_DIRS = /* @__PURE__ */ new Set([
|
|
358
|
+
"component",
|
|
359
|
+
"components",
|
|
360
|
+
"ui",
|
|
361
|
+
"uis",
|
|
362
|
+
"widget",
|
|
363
|
+
"widgets",
|
|
364
|
+
"atom",
|
|
365
|
+
"atoms",
|
|
366
|
+
"molecule",
|
|
367
|
+
"molecules",
|
|
368
|
+
"organism",
|
|
369
|
+
"organisms",
|
|
370
|
+
"layout",
|
|
371
|
+
"layouts",
|
|
372
|
+
"partial",
|
|
373
|
+
"partials"
|
|
374
|
+
]);
|
|
375
|
+
function normalizeName(x) {
|
|
376
|
+
return String(x ?? "").toLowerCase();
|
|
377
|
+
}
|
|
378
|
+
function makeIgnoreSets(opts) {
|
|
379
|
+
const ignoreDirs = new Set(DEFAULT_IGNORE_DIRS);
|
|
380
|
+
const componentLikeDirs = new Set(DEFAULT_COMPONENT_LIKE_DIRS);
|
|
381
|
+
for (const d of opts?.ignoreDirs ?? []) ignoreDirs.add(normalizeName(d));
|
|
382
|
+
for (const d of opts?.componentLikeDirs ?? []) componentLikeDirs.add(normalizeName(d));
|
|
383
|
+
return { ignoreDirs, componentLikeDirs };
|
|
384
|
+
}
|
|
385
|
+
function isIgnoredDir(dirName, sets) {
|
|
386
|
+
const name = normalizeName(dirName);
|
|
387
|
+
return sets.ignoreDirs.has(name) || sets.componentLikeDirs.has(name);
|
|
388
|
+
}
|
|
389
|
+
function writeAppEntryFile(inputs, srcRoot, appEntryName) {
|
|
390
|
+
const app = import_node_path2.default.join(srcRoot, appEntryName);
|
|
391
|
+
const lines = ["// Auto-generated \u2013 do not edit", ""];
|
|
392
|
+
const entries = Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b));
|
|
393
|
+
for (const [name, full] of entries) {
|
|
394
|
+
const rel = "./" + import_node_path2.default.relative(srcRoot, full).replace(/\\/g, "/").replace(EXT_PATTERN, "");
|
|
395
|
+
const variable = name.replace(/[^a-zA-Z0-9_$]/g, "_").replace(/^(\d)/, "_$1");
|
|
396
|
+
lines.push(`import * as ${variable} from '${rel}';`);
|
|
397
|
+
lines.push(`console.log('${name} loaded:', ${variable});`, "");
|
|
398
|
+
}
|
|
399
|
+
fs.writeFileSync(app, lines.join("\n"), "utf8");
|
|
400
|
+
console.log(`\u2705 Generated ${appEntryName} in ${srcRoot}`);
|
|
401
|
+
}
|
|
402
|
+
function pathToKey(relNoExt, opts) {
|
|
403
|
+
let normalized = relNoExt.replace(/\\/g, "/");
|
|
404
|
+
if (opts.collapseIndex) {
|
|
405
|
+
normalized = normalized.replace(/\/index$/i, "");
|
|
406
|
+
}
|
|
407
|
+
let key = normalized.split("/").filter(Boolean).join(".");
|
|
408
|
+
if (!key) key = "index";
|
|
409
|
+
return key;
|
|
410
|
+
}
|
|
411
|
+
function crawl(dirPath, baseDir, acc, sets, appEntryAbsPath) {
|
|
412
|
+
if (!fs.existsSync(dirPath)) return;
|
|
413
|
+
for (const item of fs.readdirSync(dirPath)) {
|
|
414
|
+
const full = import_node_path2.default.join(dirPath, item);
|
|
415
|
+
const stat = fs.statSync(full);
|
|
416
|
+
if (stat.isDirectory()) {
|
|
417
|
+
if (isIgnoredDir(item, sets)) continue;
|
|
418
|
+
crawl(full, baseDir, acc, sets, appEntryAbsPath);
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
if (!EXT_PATTERN.test(item)) continue;
|
|
422
|
+
if (import_node_path2.default.resolve(full) === import_node_path2.default.resolve(appEntryAbsPath)) {
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
const relNoExt = import_node_path2.default.relative(baseDir, full).replace(EXT_PATTERN, "");
|
|
426
|
+
const isIndexFile = /(^|[\\/])index$/i.test(relNoExt);
|
|
427
|
+
const preferred = pathToKey(relNoExt, { collapseIndex: true });
|
|
428
|
+
const explicit = pathToKey(relNoExt, { collapseIndex: false });
|
|
429
|
+
let name = preferred;
|
|
430
|
+
const existing = acc[name];
|
|
431
|
+
if (existing && import_node_path2.default.resolve(existing) !== import_node_path2.default.resolve(full)) {
|
|
432
|
+
if (isIndexFile) {
|
|
433
|
+
if (!acc[explicit]) {
|
|
434
|
+
console.warn(
|
|
435
|
+
`\u26A0\uFE0F Key collision for "${preferred}" \u2014 using "${explicit}" for index file`,
|
|
436
|
+
{ existing: acc[preferred], incoming: full }
|
|
437
|
+
);
|
|
438
|
+
name = explicit;
|
|
439
|
+
} else {
|
|
440
|
+
let i = 2;
|
|
441
|
+
let next = `${explicit}__${i}`;
|
|
442
|
+
while (acc[next]) {
|
|
443
|
+
i += 1;
|
|
444
|
+
next = `${explicit}__${i}`;
|
|
445
|
+
}
|
|
446
|
+
console.warn(`\u26A0\uFE0F Key collision for "${explicit}" \u2014 using "${next}"`, {
|
|
447
|
+
existing: acc[explicit],
|
|
448
|
+
incoming: full
|
|
449
|
+
});
|
|
450
|
+
name = next;
|
|
451
|
+
}
|
|
452
|
+
} else {
|
|
453
|
+
let i = 2;
|
|
454
|
+
let next = `${name}__${i}`;
|
|
455
|
+
while (acc[next]) {
|
|
456
|
+
i += 1;
|
|
457
|
+
next = `${name}__${i}`;
|
|
458
|
+
}
|
|
459
|
+
console.warn(`\u26A0\uFE0F Input key collision "${name}" -> using "${next}"`, {
|
|
460
|
+
existing: acc[name],
|
|
461
|
+
incoming: full
|
|
462
|
+
});
|
|
463
|
+
name = next;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
acc[name] = full;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function generatePluginInputs(srcRoot = import_node_path2.default.resolve(process.cwd(), "ts"), options = {}) {
|
|
470
|
+
const {
|
|
471
|
+
writeAppEntry = true,
|
|
472
|
+
appEntryName = "app.tsx",
|
|
473
|
+
includeAppEntryInInputs = true,
|
|
474
|
+
appEntryKey = "__app_entry",
|
|
475
|
+
verbose = true
|
|
476
|
+
} = options;
|
|
477
|
+
const absRoot = import_node_path2.default.resolve(srcRoot);
|
|
478
|
+
const inputs = {};
|
|
479
|
+
const sets = makeIgnoreSets(options);
|
|
480
|
+
const appEntryAbsPath = import_node_path2.default.join(absRoot, appEntryName);
|
|
481
|
+
crawl(absRoot, absRoot, inputs, sets, appEntryAbsPath);
|
|
482
|
+
if (verbose) {
|
|
483
|
+
console.log("\u2705 Integrations discovered:", inputs);
|
|
484
|
+
}
|
|
485
|
+
if (writeAppEntry) {
|
|
486
|
+
writeAppEntryFile(inputs, absRoot, appEntryName);
|
|
487
|
+
}
|
|
488
|
+
if (!includeAppEntryInInputs) return inputs;
|
|
489
|
+
return { ...inputs, [appEntryKey]: appEntryAbsPath };
|
|
490
|
+
}
|
|
342
491
|
// Annotate the CommonJS export names for ESM import in node:
|
|
343
492
|
0 && (module.exports = {
|
|
493
|
+
discoverEntrypoints,
|
|
344
494
|
fortiPrepTransform
|
|
345
495
|
});
|
|
346
496
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/vite/prep.ts","../src/babel/transform.ts"],"sourcesContent":["// src/index.ts\r\nexport { default } from \"./vite/prep\";\r\nexport type { FortiPrepOptions } from \"./vite/prep\";\r\nexport type { FortiPrepTransformOptions } from \"./babel/transform\";\r\n\r\n// ✅ add this:\r\nexport { default as fortiPrepTransform } from \"./babel/transform\";","import { transformSync } from \"@babel/core\";\r\nimport { readFileSync, writeFileSync } from \"node:fs\";\r\nimport { dirname, resolve as resolvePath } from \"node:path\";\r\nimport type {NormalizedOutputOptions, OutputBundle, OutputOptions} from \"rollup\";\r\nimport type { Plugin as VitePlugin } from \"vite\";\r\n\r\nimport fortiPrepTransform, {\r\n type FortiPrepTransformOptions,\r\n} from \"../babel/transform\";\r\n\r\nexport type FortiPrepOptions = FortiPrepTransformOptions & {\r\n /**\r\n * Which emitted entry file extensions should be rewritten.\r\n * Default: [\".js\", \".mjs\"]\r\n */\r\n entryExtensions?: string[];\r\n\r\n /**\r\n * Vite plugin name\r\n * Default: \"fortiplugin-prep\"\r\n */\r\n pluginName?: string;\r\n};\r\n\r\nconst DEFAULT_INJECTED_IDS = [\"react\", \"react/jsx-runtime\"] as const;\r\nconst DEFAULT_INJECTED_PREFIXES = [\"@inertiajs/\", \"@host/\"] as const;\r\n\r\nfunction resolveOutDir(outputOptions: OutputOptions): string | null {\r\n if (outputOptions.dir) return outputOptions.dir;\r\n if (outputOptions.file) return dirname(outputOptions.file);\r\n return null;\r\n}\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * FortiPlugin bundle adapter:\r\n * - marks injected imports as Rollup externals (so they survive into output)\r\n * - rewrites built entry chunks to remove those imports and load them from runtime deps\r\n */\r\nexport default function prep(options: FortiPrepOptions = {}): VitePlugin {\r\n const injectedIds = options.injectedIds ?? [...DEFAULT_INJECTED_IDS];\r\n const injectedPrefixes = options.injectedPrefixes ?? [...DEFAULT_INJECTED_PREFIXES];\r\n\r\n const runtimeKey = options.runtimeKey ?? \"imports\";\r\n const depsParam = options.depsParam ?? \"deps\";\r\n\r\n const entryExtensions = options.entryExtensions ?? [\".js\", \".mjs\"];\r\n const pluginName = options.pluginName ?? \"fortiplugin-prep\";\r\n\r\n const transformOptions: FortiPrepTransformOptions = {\r\n injectedIds,\r\n injectedPrefixes,\r\n runtimeKey,\r\n depsParam,\r\n };\r\n\r\n return {\r\n name: pluginName,\r\n apply: \"build\",\r\n\r\n config() {\r\n return {\r\n define: {\r\n \"process.env.NODE_ENV\": '\"production\"',\r\n },\r\n build: {\r\n rollupOptions: {\r\n // Ensure virtual imports don't need to resolve.\r\n external: (id: string) => shouldInject(id, transformOptions),\r\n },\r\n },\r\n };\r\n },\r\n\r\n writeBundle(outputOptions: NormalizedOutputOptions, bundle: OutputBundle) {\r\n const outDir = resolveOutDir(outputOptions);\r\n if (!outDir) return;\r\n\r\n for (const [fileName, item] of Object.entries(bundle)) {\r\n if (item.type !== \"chunk\") continue;\r\n if (!item.isEntry) continue;\r\n\r\n if (!entryExtensions.some((ext) => fileName.endsWith(ext))) continue;\r\n\r\n const absPath = resolvePath(outDir, fileName);\r\n const input = readFileSync(absPath, \"utf-8\");\r\n\r\n const result = transformSync(input, {\r\n filename: absPath,\r\n sourceType: \"module\",\r\n // Fresh plugin instance per file (Babel calls plugin factory per file when passed as [fn, opts])\r\n plugins: [[fortiPrepTransform as any, transformOptions]],\r\n generatorOpts: {\r\n compact: false,\r\n comments: true,\r\n retainLines: false,\r\n },\r\n });\r\n\r\n if (!result?.code) continue;\r\n writeFileSync(absPath, result.code, \"utf-8\");\r\n }\r\n },\r\n };\r\n}","// noinspection JSUnusedGlobalSymbols,GrazieInspection\r\n\r\nimport type {PluginObj} from \"@babel/core\";\r\nimport * as t from \"@babel/types\";\r\nimport type {NodePath} from \"@babel/traverse\";\r\n\r\nexport type FortiPrepTransformOptions = {\r\n /**\r\n * Exact import ids to inject (removed from bundle and loaded from runtime deps).\r\n * Example: [\"react\", \"react/jsx-runtime\", \"@host/ui\"]\r\n */\r\n injectedIds?: string[];\r\n\r\n /**\r\n * Prefix import ids to inject.\r\n * Example: [\"@host/\", \"@inertiajs/\"]\r\n */\r\n injectedPrefixes?: string[];\r\n\r\n /**\r\n * The key on the deps object used as the import map.\r\n * Wrapper supports passing deps.imports OR passing the import map directly.\r\n *\r\n * Default: \"imports\"\r\n */\r\n runtimeKey?: string;\r\n\r\n /**\r\n * Wrapper function parameter name.\r\n * Default: \"deps\"\r\n */\r\n depsParam?: string;\r\n};\r\n\r\nconst DEFAULTS: Required<Pick<FortiPrepTransformOptions, \"runtimeKey\" | \"depsParam\">> = {\r\n runtimeKey: \"imports\",\r\n depsParam: \"deps\",\r\n};\r\n\r\nconst DEFAULT_EXPORT_ERROR =\r\n \"PROBLEM!!, No known default function was found, your code either possesses NO named default export or this export format is currently not supported.\";\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\ntype CapturedImport =\r\n | { kind: \"default\"; local: string }\r\n | { kind: \"namespace\"; local: string }\r\n | { kind: \"named\"; imported: string; local: string };\r\n\r\nfunction getImportedName(spec: t.ImportSpecifier): string {\r\n return t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;\r\n}\r\n\r\nfunction makeImportMapExpr(\r\n depsIdent: t.Identifier,\r\n runtimeKey: string\r\n): t.Expression {\r\n // Support both:\r\n // factory({ imports: { ... } })\r\n // and:\r\n // factory({ ... }) // direct import map\r\n //\r\n // const __imports =\r\n // deps && typeof deps === \"object\" && \"imports\" in deps\r\n // ? deps.imports\r\n // : (deps ?? {});\r\n const hasKey = t.binaryExpression(\r\n \"in\",\r\n t.stringLiteral(runtimeKey),\r\n depsIdent\r\n );\r\n\r\n const isObj = t.logicalExpression(\r\n \"&&\",\r\n t.binaryExpression(\"!==\", depsIdent, t.nullLiteral()),\r\n t.binaryExpression(\"===\", t.unaryExpression(\"typeof\", depsIdent), t.stringLiteral(\"object\"))\r\n );\r\n\r\n const test = t.logicalExpression(\"&&\", isObj, hasKey);\r\n\r\n const depsKey = t.memberExpression(depsIdent, t.identifier(runtimeKey));\r\n const fallback = t.logicalExpression(\"||\", depsIdent, t.objectExpression([]));\r\n\r\n return t.conditionalExpression(test, depsKey, fallback);\r\n}\r\n\r\n/**\r\n * Babel plugin factory (Babel calls this per-file when used as `[plugin, options]`).\r\n */\r\nexport default function fortiPrepTransform(\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n _api: unknown,\r\n rawOpts: FortiPrepTransformOptions = {}\r\n): PluginObj {\r\n const opts: FortiPrepTransformOptions = {\r\n ...rawOpts,\r\n runtimeKey: rawOpts.runtimeKey ?? DEFAULTS.runtimeKey,\r\n depsParam: rawOpts.depsParam ?? DEFAULTS.depsParam,\r\n };\r\n\r\n // per-file state (because Babel calls the plugin per file)\r\n const keptImports: t.ImportDeclaration[] = [];\r\n const keptNamedExports: t.ExportNamedDeclaration[] = [];\r\n\r\n const injectedImportsById = new Map<string, CapturedImport[]>();\r\n\r\n let defaultExportLocalName: string | null = null;\r\n let returnDefaultProperty = false;\r\n\r\n function captureImport(importId: string, entry: CapturedImport) {\r\n const list = injectedImportsById.get(importId) ?? [];\r\n list.push(entry);\r\n injectedImportsById.set(importId, list);\r\n }\r\n\r\n return {\r\n name: \"fortiplugin-prep/transform\",\r\n visitor: {\r\n ImportDeclaration(path: NodePath<t.ImportDeclaration>) {\r\n const node = path.node;\r\n const importId = node.source.value;\r\n\r\n if (!shouldInject(importId, opts)) {\r\n keptImports.push(node);\r\n path.remove();\r\n return;\r\n }\r\n\r\n // Remove injected import and capture its specifiers to recreate inside wrapper.\r\n for (const s of node.specifiers) {\r\n if (t.isImportDefaultSpecifier(s)) {\r\n captureImport(importId, {kind: \"default\", local: s.local.name});\r\n } else if (t.isImportNamespaceSpecifier(s)) {\r\n captureImport(importId, {kind: \"namespace\", local: s.local.name});\r\n } else if (t.isImportSpecifier(s)) {\r\n captureImport(importId, {\r\n kind: \"named\",\r\n imported: getImportedName(s),\r\n local: s.local.name,\r\n });\r\n }\r\n }\r\n\r\n // side-effect only imports (import \"@host/ui\") become no-ops at runtime\r\n path.remove();\r\n },\r\n\r\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\r\n const decl = path.node.declaration;\r\n\r\n // export default Foo;\r\n if (t.isIdentifier(decl)) {\r\n defaultExportLocalName = decl.name;\r\n path.remove();\r\n return;\r\n }\r\n\r\n // export default (expr/anon fn/class)\r\n // Hoist into a const (inside wrapper) so we can `return <id>`\r\n const id = path.scope.generateUidIdentifier(\"defaultExport\");\r\n path.replaceWith(\r\n t.variableDeclaration(\"const\", [t.variableDeclarator(id, decl as any)])\r\n );\r\n defaultExportLocalName = id.name;\r\n },\r\n\r\n ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {\r\n const node = path.node;\r\n keptNamedExports.push(node);\r\n\r\n // Detect Rollup-style: export { Foo as default }\r\n if (node.specifiers?.length) {\r\n let foundExplicitDefault = false;\r\n\r\n node.specifiers = node.specifiers.filter((spec) => {\r\n const exported =\r\n t.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value;\r\n\r\n if (exported === \"default\") {\r\n const local = (spec as any)?.local?.name as string | undefined;\r\n if (local) defaultExportLocalName = local;\r\n foundExplicitDefault = true;\r\n return false; // remove\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Minified fallback behavior:\r\n // If no default specifier found and exactly one spec exists,\r\n // treat it as the container and return `<local>.default`.\r\n if (!foundExplicitDefault && !defaultExportLocalName && node.specifiers.length === 1) {\r\n const only = node.specifiers[0] as any;\r\n if (only?.local?.name) {\r\n defaultExportLocalName = only.local.name;\r\n returnDefaultProperty = true;\r\n node.specifiers = [];\r\n }\r\n }\r\n }\r\n\r\n path.remove();\r\n },\r\n\r\n Program: {\r\n exit(path: NodePath<t.Program>) {\r\n const program = path.node;\r\n\r\n if (!defaultExportLocalName) {\r\n throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);\r\n }\r\n\r\n const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);\r\n const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;\r\n\r\n // const __imports = (deps has runtimeKey) ? deps[runtimeKey] : (deps || {});\r\n const importsIdent = t.identifier(\"__imports\");\r\n const importsInit = makeImportMapExpr(depsIdent, runtimeKey);\r\n const importsDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(importsIdent, importsInit),\r\n ]);\r\n\r\n // helper:\r\n // const __default = (m) => (m && typeof m === \"object\" && \"default\" in m ? m.default : m);\r\n const defaultHelperIdent = t.identifier(\"__default\");\r\n const defaultHelperDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n defaultHelperIdent,\r\n t.arrowFunctionExpression(\r\n [t.identifier(\"m\")],\r\n t.conditionalExpression(\r\n t.logicalExpression(\r\n \"&&\",\r\n t.logicalExpression(\r\n \"&&\",\r\n t.identifier(\"m\"),\r\n t.binaryExpression(\r\n \"===\",\r\n t.unaryExpression(\"typeof\", t.identifier(\"m\")),\r\n t.stringLiteral(\"object\")\r\n )\r\n ),\r\n t.binaryExpression(\"in\", t.stringLiteral(\"default\"), t.identifier(\"m\"))\r\n ),\r\n t.memberExpression(t.identifier(\"m\"), t.identifier(\"default\")),\r\n t.identifier(\"m\")\r\n )\r\n )\r\n ),\r\n ]);\r\n\r\n // Build injected module locals inside wrapper\r\n const injectedStmts: t.Statement[] = [importsDecl, defaultHelperDecl];\r\n\r\n for (const [importId, specs] of injectedImportsById.entries()) {\r\n const modIdent = t.identifier(\r\n `__m_${importId.replace(/[^a-zA-Z0-9_$]/g, \"_\")}`\r\n );\r\n\r\n // const __m_xxx = __imports[\"<importId>\"];\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n modIdent,\r\n t.memberExpression(importsIdent, t.stringLiteral(importId), true)\r\n ),\r\n ])\r\n );\r\n\r\n const named: Array<{ imported: string; local: string }> = [];\r\n\r\n for (const s of specs) {\r\n if (s.kind === \"default\") {\r\n // const Local = __default(__m_xxx);\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.identifier(s.local),\r\n t.callExpression(defaultHelperIdent, [modIdent])\r\n ),\r\n ])\r\n );\r\n } else if (s.kind === \"namespace\") {\r\n // const Local = __m_xxx;\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(t.identifier(s.local), modIdent),\r\n ])\r\n );\r\n } else {\r\n named.push({imported: s.imported, local: s.local});\r\n }\r\n }\r\n\r\n if (named.length) {\r\n // const { A, B: C } = (__m_xxx ?? {});\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.objectPattern(\r\n named.map(({imported, local}) =>\r\n t.objectProperty(\r\n t.identifier(imported),\r\n t.identifier(local),\r\n false,\r\n imported === local\r\n )\r\n )\r\n ),\r\n t.logicalExpression(\"||\", modIdent, t.objectExpression([]))\r\n ),\r\n ])\r\n );\r\n }\r\n }\r\n\r\n const returnExpr = returnDefaultProperty\r\n ? t.memberExpression(\r\n t.identifier(defaultExportLocalName),\r\n t.identifier(\"default\")\r\n )\r\n : t.identifier(defaultExportLocalName);\r\n\r\n // Wrapper body:\r\n // injectedStmts...\r\n // <original body>\r\n // return <defaultExport>\r\n const wrapperBody: t.Statement[] = [];\r\n wrapperBody.push(...injectedStmts);\r\n wrapperBody.push(...program.body);\r\n wrapperBody.push(t.returnStatement(returnExpr));\r\n\r\n const wrapper = t.exportDefaultDeclaration(\r\n t.functionDeclaration(\r\n null,\r\n [depsIdent],\r\n t.blockStatement(wrapperBody)\r\n )\r\n );\r\n\r\n // Final program:\r\n // kept imports at module scope\r\n // export default function(deps) { ... }\r\n // kept named exports (same as your old behavior)\r\n program.body = [...keptImports, wrapper, ...keptNamedExports] as any;\r\n },\r\n },\r\n },\r\n };\r\n}"],"mappings":"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","names":["shouldInject","resolvePath"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/vite/prep.ts","../src/babel/transform.ts","../src/utils/generate-plugin-inputs.ts"],"sourcesContent":["// src/index.ts\r\nexport {default} from \"./vite/prep\";\r\nexport type {FortiPrepOptions} from \"./vite/prep\";\r\nexport type {FortiPrepTransformOptions} from \"./babel/transform\";\r\n\r\n// ✅ add this:\r\nexport {default as fortiPrepTransform} from \"./babel/transform\";\r\nexport {generatePluginInputs as discoverEntrypoints} from './utils/generate-plugin-inputs'","import { transformSync } from \"@babel/core\";\r\nimport { readFileSync, writeFileSync } from \"node:fs\";\r\nimport { dirname, resolve as resolvePath } from \"node:path\";\r\nimport type {NormalizedOutputOptions, OutputBundle, OutputOptions} from \"rollup\";\r\nimport type { Plugin as VitePlugin } from \"vite\";\r\n\r\nimport fortiPrepTransform, {\r\n type FortiPrepTransformOptions,\r\n} from \"../babel/transform\";\r\n\r\nexport type FortiPrepOptions = FortiPrepTransformOptions & {\r\n /**\r\n * Which emitted entry file extensions should be rewritten.\r\n * Default: [\".js\", \".mjs\"]\r\n */\r\n entryExtensions?: string[];\r\n\r\n /**\r\n * Vite plugin name\r\n * Default: \"fortiplugin-prep\"\r\n */\r\n pluginName?: string;\r\n};\r\n\r\nconst DEFAULT_INJECTED_IDS = [\"react\", \"react/jsx-runtime\"] as const;\r\nconst DEFAULT_INJECTED_PREFIXES = [\"@inertiajs/\", \"@host/\"] as const;\r\n\r\nfunction resolveOutDir(outputOptions: OutputOptions): string | null {\r\n if (outputOptions.dir) return outputOptions.dir;\r\n if (outputOptions.file) return dirname(outputOptions.file);\r\n return null;\r\n}\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * FortiPlugin bundle adapter:\r\n * - marks injected imports as Rollup externals (so they survive into output)\r\n * - rewrites built entry chunks to remove those imports and load them from runtime deps\r\n */\r\nexport default function prep(options: FortiPrepOptions = {}): VitePlugin {\r\n const injectedIds = options.injectedIds ?? [...DEFAULT_INJECTED_IDS];\r\n const injectedPrefixes = options.injectedPrefixes ?? [...DEFAULT_INJECTED_PREFIXES];\r\n\r\n const runtimeKey = options.runtimeKey ?? \"imports\";\r\n const depsParam = options.depsParam ?? \"deps\";\r\n\r\n const entryExtensions = options.entryExtensions ?? [\".js\", \".mjs\"];\r\n const pluginName = options.pluginName ?? \"fortiplugin-prep\";\r\n\r\n const transformOptions: FortiPrepTransformOptions = {\r\n injectedIds,\r\n injectedPrefixes,\r\n runtimeKey,\r\n depsParam,\r\n };\r\n\r\n return {\r\n name: pluginName,\r\n apply: \"build\",\r\n\r\n config() {\r\n return {\r\n define: {\r\n \"process.env.NODE_ENV\": '\"production\"',\r\n },\r\n build: {\r\n rollupOptions: {\r\n // Ensure virtual imports don't need to resolve.\r\n external: (id: string) => shouldInject(id, transformOptions),\r\n },\r\n },\r\n };\r\n },\r\n\r\n writeBundle(outputOptions: NormalizedOutputOptions, bundle: OutputBundle) {\r\n const outDir = resolveOutDir(outputOptions);\r\n if (!outDir) return;\r\n\r\n for (const [fileName, item] of Object.entries(bundle)) {\r\n if (item.type !== \"chunk\") continue;\r\n if (!item.isEntry) continue;\r\n\r\n if (!entryExtensions.some((ext) => fileName.endsWith(ext))) continue;\r\n\r\n const absPath = resolvePath(outDir, fileName);\r\n const input = readFileSync(absPath, \"utf-8\");\r\n\r\n const result = transformSync(input, {\r\n filename: absPath,\r\n sourceType: \"module\",\r\n // Fresh plugin instance per file (Babel calls plugin factory per file when passed as [fn, opts])\r\n plugins: [[fortiPrepTransform as any, transformOptions]],\r\n generatorOpts: {\r\n compact: false,\r\n comments: true,\r\n retainLines: false,\r\n },\r\n });\r\n\r\n if (!result?.code) continue;\r\n writeFileSync(absPath, result.code, \"utf-8\");\r\n }\r\n },\r\n };\r\n}","// noinspection JSUnusedGlobalSymbols,GrazieInspection\r\n\r\nimport type {PluginObj} from \"@babel/core\";\r\nimport * as t from \"@babel/types\";\r\nimport type {NodePath} from \"@babel/traverse\";\r\n\r\nexport type FortiPrepTransformOptions = {\r\n /**\r\n * Exact import ids to inject (removed from bundle and loaded from runtime deps).\r\n * Example: [\"react\", \"react/jsx-runtime\", \"@host/ui\"]\r\n */\r\n injectedIds?: string[];\r\n\r\n /**\r\n * Prefix import ids to inject.\r\n * Example: [\"@host/\", \"@inertiajs/\"]\r\n */\r\n injectedPrefixes?: string[];\r\n\r\n /**\r\n * The key on the deps object used as the import map.\r\n * Wrapper supports passing deps.imports OR passing the import map directly.\r\n *\r\n * Default: \"imports\"\r\n */\r\n runtimeKey?: string;\r\n\r\n /**\r\n * Wrapper function parameter name.\r\n * Default: \"deps\"\r\n */\r\n depsParam?: string;\r\n};\r\n\r\nconst DEFAULTS: Required<Pick<FortiPrepTransformOptions, \"runtimeKey\" | \"depsParam\">> = {\r\n runtimeKey: \"imports\",\r\n depsParam: \"deps\",\r\n};\r\n\r\nconst DEFAULT_EXPORT_ERROR =\r\n \"PROBLEM!!, No known default function was found, your code either possesses NO named default export or this export format is currently not supported.\";\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\ntype CapturedImport =\r\n | { kind: \"default\"; local: string }\r\n | { kind: \"namespace\"; local: string }\r\n | { kind: \"named\"; imported: string; local: string };\r\n\r\nfunction getImportedName(spec: t.ImportSpecifier): string {\r\n return t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;\r\n}\r\n\r\nfunction makeImportMapExpr(\r\n depsIdent: t.Identifier,\r\n runtimeKey: string\r\n): t.Expression {\r\n // Support both:\r\n // factory({ imports: { ... } })\r\n // and:\r\n // factory({ ... }) // direct import map\r\n //\r\n // const __imports =\r\n // deps && typeof deps === \"object\" && \"imports\" in deps\r\n // ? deps.imports\r\n // : (deps ?? {});\r\n const hasKey = t.binaryExpression(\r\n \"in\",\r\n t.stringLiteral(runtimeKey),\r\n depsIdent\r\n );\r\n\r\n const isObj = t.logicalExpression(\r\n \"&&\",\r\n t.binaryExpression(\"!==\", depsIdent, t.nullLiteral()),\r\n t.binaryExpression(\"===\", t.unaryExpression(\"typeof\", depsIdent), t.stringLiteral(\"object\"))\r\n );\r\n\r\n const test = t.logicalExpression(\"&&\", isObj, hasKey);\r\n\r\n const depsKey = t.memberExpression(depsIdent, t.identifier(runtimeKey));\r\n const fallback = t.logicalExpression(\"||\", depsIdent, t.objectExpression([]));\r\n\r\n return t.conditionalExpression(test, depsKey, fallback);\r\n}\r\n\r\n/**\r\n * Babel plugin factory (Babel calls this per-file when used as `[plugin, options]`).\r\n */\r\nexport default function fortiPrepTransform(\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n _api: unknown,\r\n rawOpts: FortiPrepTransformOptions = {}\r\n): PluginObj {\r\n const opts: FortiPrepTransformOptions = {\r\n ...rawOpts,\r\n runtimeKey: rawOpts.runtimeKey ?? DEFAULTS.runtimeKey,\r\n depsParam: rawOpts.depsParam ?? DEFAULTS.depsParam,\r\n };\r\n\r\n // per-file state (because Babel calls the plugin per file)\r\n const keptImports: t.ImportDeclaration[] = [];\r\n const keptNamedExports: t.ExportNamedDeclaration[] = [];\r\n\r\n const injectedImportsById = new Map<string, CapturedImport[]>();\r\n\r\n let defaultExportLocalName: string | null = null;\r\n let returnDefaultProperty = false;\r\n\r\n function captureImport(importId: string, entry: CapturedImport) {\r\n const list = injectedImportsById.get(importId) ?? [];\r\n list.push(entry);\r\n injectedImportsById.set(importId, list);\r\n }\r\n\r\n return {\r\n name: \"fortiplugin-prep/transform\",\r\n visitor: {\r\n ImportDeclaration(path: NodePath<t.ImportDeclaration>) {\r\n const node = path.node;\r\n const importId = node.source.value;\r\n\r\n if (!shouldInject(importId, opts)) {\r\n keptImports.push(node);\r\n path.remove();\r\n return;\r\n }\r\n\r\n // Remove injected import and capture its specifiers to recreate inside wrapper.\r\n for (const s of node.specifiers) {\r\n if (t.isImportDefaultSpecifier(s)) {\r\n captureImport(importId, {kind: \"default\", local: s.local.name});\r\n } else if (t.isImportNamespaceSpecifier(s)) {\r\n captureImport(importId, {kind: \"namespace\", local: s.local.name});\r\n } else if (t.isImportSpecifier(s)) {\r\n captureImport(importId, {\r\n kind: \"named\",\r\n imported: getImportedName(s),\r\n local: s.local.name,\r\n });\r\n }\r\n }\r\n\r\n // side-effect only imports (import \"@host/ui\") become no-ops at runtime\r\n path.remove();\r\n },\r\n\r\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\r\n const decl = path.node.declaration;\r\n\r\n // export default Foo;\r\n if (t.isIdentifier(decl)) {\r\n defaultExportLocalName = decl.name;\r\n path.remove();\r\n return;\r\n }\r\n\r\n // export default (expr/anon fn/class)\r\n // Hoist into a const (inside wrapper) so we can `return <id>`\r\n const id = path.scope.generateUidIdentifier(\"defaultExport\");\r\n path.replaceWith(\r\n t.variableDeclaration(\"const\", [t.variableDeclarator(id, decl as any)])\r\n );\r\n defaultExportLocalName = id.name;\r\n },\r\n\r\n ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {\r\n const node = path.node;\r\n keptNamedExports.push(node);\r\n\r\n // Detect Rollup-style: export { Foo as default }\r\n if (node.specifiers?.length) {\r\n let foundExplicitDefault = false;\r\n\r\n node.specifiers = node.specifiers.filter((spec) => {\r\n const exported =\r\n t.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value;\r\n\r\n if (exported === \"default\") {\r\n const local = (spec as any)?.local?.name as string | undefined;\r\n if (local) defaultExportLocalName = local;\r\n foundExplicitDefault = true;\r\n return false; // remove\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Minified fallback behavior:\r\n // If no default specifier found and exactly one spec exists,\r\n // treat it as the container and return `<local>.default`.\r\n if (!foundExplicitDefault && !defaultExportLocalName && node.specifiers.length === 1) {\r\n const only = node.specifiers[0] as any;\r\n if (only?.local?.name) {\r\n defaultExportLocalName = only.local.name;\r\n returnDefaultProperty = true;\r\n node.specifiers = [];\r\n }\r\n }\r\n }\r\n\r\n path.remove();\r\n },\r\n\r\n Program: {\r\n exit(path: NodePath<t.Program>) {\r\n const program = path.node;\r\n\r\n if (!defaultExportLocalName) {\r\n throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);\r\n }\r\n\r\n const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);\r\n const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;\r\n\r\n // const __imports = (deps has runtimeKey) ? deps[runtimeKey] : (deps || {});\r\n const importsIdent = t.identifier(\"__imports\");\r\n const importsInit = makeImportMapExpr(depsIdent, runtimeKey);\r\n const importsDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(importsIdent, importsInit),\r\n ]);\r\n\r\n // helper:\r\n // const __default = (m) => (m && typeof m === \"object\" && \"default\" in m ? m.default : m);\r\n const defaultHelperIdent = t.identifier(\"__default\");\r\n const defaultHelperDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n defaultHelperIdent,\r\n t.arrowFunctionExpression(\r\n [t.identifier(\"m\")],\r\n t.conditionalExpression(\r\n t.logicalExpression(\r\n \"&&\",\r\n t.logicalExpression(\r\n \"&&\",\r\n t.identifier(\"m\"),\r\n t.binaryExpression(\r\n \"===\",\r\n t.unaryExpression(\"typeof\", t.identifier(\"m\")),\r\n t.stringLiteral(\"object\")\r\n )\r\n ),\r\n t.binaryExpression(\"in\", t.stringLiteral(\"default\"), t.identifier(\"m\"))\r\n ),\r\n t.memberExpression(t.identifier(\"m\"), t.identifier(\"default\")),\r\n t.identifier(\"m\")\r\n )\r\n )\r\n ),\r\n ]);\r\n\r\n // Build injected module locals inside wrapper\r\n const injectedStmts: t.Statement[] = [importsDecl, defaultHelperDecl];\r\n\r\n for (const [importId, specs] of injectedImportsById.entries()) {\r\n const modIdent = t.identifier(\r\n `__m_${importId.replace(/[^a-zA-Z0-9_$]/g, \"_\")}`\r\n );\r\n\r\n // const __m_xxx = __imports[\"<importId>\"];\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n modIdent,\r\n t.memberExpression(importsIdent, t.stringLiteral(importId), true)\r\n ),\r\n ])\r\n );\r\n\r\n const named: Array<{ imported: string; local: string }> = [];\r\n\r\n for (const s of specs) {\r\n if (s.kind === \"default\") {\r\n // const Local = __default(__m_xxx);\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.identifier(s.local),\r\n t.callExpression(defaultHelperIdent, [modIdent])\r\n ),\r\n ])\r\n );\r\n } else if (s.kind === \"namespace\") {\r\n // const Local = __m_xxx;\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(t.identifier(s.local), modIdent),\r\n ])\r\n );\r\n } else {\r\n named.push({imported: s.imported, local: s.local});\r\n }\r\n }\r\n\r\n if (named.length) {\r\n // const { A, B: C } = (__m_xxx ?? {});\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.objectPattern(\r\n named.map(({imported, local}) =>\r\n t.objectProperty(\r\n t.identifier(imported),\r\n t.identifier(local),\r\n false,\r\n imported === local\r\n )\r\n )\r\n ),\r\n t.logicalExpression(\"||\", modIdent, t.objectExpression([]))\r\n ),\r\n ])\r\n );\r\n }\r\n }\r\n\r\n const returnExpr = returnDefaultProperty\r\n ? t.memberExpression(\r\n t.identifier(defaultExportLocalName),\r\n t.identifier(\"default\")\r\n )\r\n : t.identifier(defaultExportLocalName);\r\n\r\n // Wrapper body:\r\n // injectedStmts...\r\n // <original body>\r\n // return <defaultExport>\r\n const wrapperBody: t.Statement[] = [];\r\n wrapperBody.push(...injectedStmts);\r\n wrapperBody.push(...program.body);\r\n wrapperBody.push(t.returnStatement(returnExpr));\r\n\r\n const wrapper = t.exportDefaultDeclaration(\r\n t.functionDeclaration(\r\n null,\r\n [depsIdent],\r\n t.blockStatement(wrapperBody)\r\n )\r\n );\r\n\r\n // Final program:\r\n // kept imports at module scope\r\n // export default function(deps) { ... }\r\n // kept named exports (same as your old behavior)\r\n program.body = [...keptImports, wrapper, ...keptNamedExports] as any;\r\n },\r\n },\r\n },\r\n };\r\n}","// src/utils/generate-plugin-inputs.ts\r\nimport path from \"node:path\";\r\nimport * as fs from \"node:fs\";\r\n\r\nconst EXT_PATTERN = /\\.(tsx?|jsx?)$/i;\r\n\r\nexport type PluginInputs = Record<string, string>;\r\n\r\nexport type GeneratePluginInputsOptions = {\r\n /**\r\n * If true, also generates `app.tsx` that imports every discovered entry\r\n * (handy for dev/HMR).\r\n *\r\n * Default: true\r\n */\r\n writeAppEntry?: boolean;\r\n\r\n /**\r\n * Name of the generated app entry file (inside srcRoot).\r\n *\r\n * Default: \"app.tsx\"\r\n */\r\n appEntryName?: string;\r\n\r\n /**\r\n * Adds the generated app entry to the returned Rollup inputs map.\r\n *\r\n * Default: true\r\n */\r\n includeAppEntryInInputs?: boolean;\r\n\r\n /**\r\n * Key name used for the generated app entry in Rollup inputs.\r\n *\r\n * Default: \"__app_entry\"\r\n */\r\n appEntryKey?: string;\r\n\r\n /**\r\n * Extra directory names to ignore (case-insensitive).\r\n */\r\n ignoreDirs?: string[];\r\n\r\n /**\r\n * Extra “component-like” directory names to ignore (case-insensitive, exact match).\r\n */\r\n componentLikeDirs?: string[];\r\n\r\n /**\r\n * Whether to print discovered inputs to console.\r\n *\r\n * Default: true\r\n */\r\n verbose?: boolean;\r\n};\r\n\r\n// folders you typically never want as rollup inputs\r\nconst DEFAULT_IGNORE_DIRS = new Set<string>([\r\n \"node_modules\",\r\n \".git\",\r\n \".vite\",\r\n \".internal\",\r\n \"dist\",\r\n \"build\",\r\n \"public\",\r\n]);\r\n\r\n// “component-like” folders that should NOT produce entrypoints\r\n// Strict: exact folder-name matches only (case-insensitive)\r\nconst DEFAULT_COMPONENT_LIKE_DIRS = new Set<string>([\r\n \"component\",\r\n \"components\",\r\n \"ui\",\r\n \"uis\",\r\n \"widget\",\r\n \"widgets\",\r\n \"atom\",\r\n \"atoms\",\r\n \"molecule\",\r\n \"molecules\",\r\n \"organism\",\r\n \"organisms\",\r\n \"layout\",\r\n \"layouts\",\r\n \"partial\",\r\n \"partials\",\r\n]);\r\n\r\nfunction normalizeName(x: unknown): string {\r\n return String(x ?? \"\").toLowerCase();\r\n}\r\n\r\nfunction makeIgnoreSets(opts?: GeneratePluginInputsOptions): {\r\n ignoreDirs: Set<string>;\r\n componentLikeDirs: Set<string>;\r\n} {\r\n const ignoreDirs = new Set(DEFAULT_IGNORE_DIRS);\r\n const componentLikeDirs = new Set(DEFAULT_COMPONENT_LIKE_DIRS);\r\n\r\n for (const d of opts?.ignoreDirs ?? []) ignoreDirs.add(normalizeName(d));\r\n for (const d of opts?.componentLikeDirs ?? []) componentLikeDirs.add(normalizeName(d));\r\n\r\n return { ignoreDirs, componentLikeDirs };\r\n}\r\n\r\nfunction isIgnoredDir(\r\n dirName: string,\r\n sets: { ignoreDirs: Set<string>; componentLikeDirs: Set<string> }\r\n): boolean {\r\n const name = normalizeName(dirName);\r\n return sets.ignoreDirs.has(name) || sets.componentLikeDirs.has(name);\r\n}\r\n\r\n/**\r\n * Creates an app.tsx file that simply imports every discovered entry.\r\n * Helpful for HMR / dev mode.\r\n */\r\nfunction writeAppEntryFile(inputs: PluginInputs, srcRoot: string, appEntryName: string): void {\r\n const app = path.join(srcRoot, appEntryName);\r\n const lines: string[] = [\"// Auto-generated – do not edit\", \"\"];\r\n\r\n const entries = Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b));\r\n\r\n for (const [name, full] of entries) {\r\n const rel =\r\n \"./\" + path.relative(srcRoot, full).replace(/\\\\/g, \"/\").replace(EXT_PATTERN, \"\");\r\n\r\n const variable = name.replace(/[^a-zA-Z0-9_$]/g, \"_\").replace(/^(\\d)/, \"_$1\");\r\n\r\n lines.push(`import * as ${variable} from '${rel}';`);\r\n lines.push(`console.log('${name} loaded:', ${variable});`, \"\");\r\n }\r\n\r\n fs.writeFileSync(app, lines.join(\"\\n\"), \"utf8\");\r\n // eslint-disable-next-line no-console\r\n console.log(`✅ Generated ${appEntryName} in ${srcRoot}`);\r\n}\r\n\r\n/**\r\n * Convert a relative path like \"foo/bar/index.tsx\" to a dot key.\r\n * If `collapseIndex` is true, \"foo/bar/index\" becomes \"foo.bar\".\r\n * Otherwise it becomes \"foo.bar.index\".\r\n */\r\nfunction pathToKey(relNoExt: string, opts: { collapseIndex: boolean }): string {\r\n let normalized = relNoExt.replace(/\\\\/g, \"/\");\r\n\r\n if (opts.collapseIndex) {\r\n normalized = normalized.replace(/\\/index$/i, \"\");\r\n }\r\n\r\n let key = normalized.split(\"/\").filter(Boolean).join(\".\");\r\n if (!key) key = \"index\";\r\n return key;\r\n}\r\n\r\n/**\r\n * Recursively collect entry files under dirPath.\r\n *\r\n * Rule:\r\n * - Prefer collapsing \".../index.tsx\" => \"...\" for nicer keys\r\n * - BUT if that key would collide with another entry, fallback to explicit \"...index\"\r\n * (e.g. \"foo.index\") for the index file ONLY.\r\n */\r\nfunction crawl(\r\n dirPath: string,\r\n baseDir: string,\r\n acc: PluginInputs,\r\n sets: { ignoreDirs: Set<string>; componentLikeDirs: Set<string> },\r\n appEntryAbsPath: string\r\n): void {\r\n if (!fs.existsSync(dirPath)) return;\r\n\r\n for (const item of fs.readdirSync(dirPath)) {\r\n const full = path.join(dirPath, item);\r\n const stat = fs.statSync(full);\r\n\r\n if (stat.isDirectory()) {\r\n if (isIgnoredDir(item, sets)) continue;\r\n crawl(full, baseDir, acc, sets, appEntryAbsPath);\r\n continue;\r\n }\r\n\r\n if (!EXT_PATTERN.test(item)) continue;\r\n\r\n // Don't include the generated entry itself (prevents self-import)\r\n if (path.resolve(full) === path.resolve(appEntryAbsPath)) {\r\n continue;\r\n }\r\n\r\n const relNoExt = path.relative(baseDir, full).replace(EXT_PATTERN, \"\");\r\n const isIndexFile = /(^|[\\\\/])index$/i.test(relNoExt);\r\n\r\n // Preferred key: collapse \".../index\" => \"...\"\r\n const preferred = pathToKey(relNoExt, { collapseIndex: true });\r\n\r\n // Explicit key: keep \".../index\" => \"...index\"\r\n // Example: \"foo/index\" => \"foo.index\"\r\n const explicit = pathToKey(relNoExt, { collapseIndex: false });\r\n\r\n let name = preferred;\r\n\r\n // If preferred collides, ONLY the index file switches to explicit path key.\r\n const existing = acc[name];\r\n if (existing && path.resolve(existing) !== path.resolve(full)) {\r\n if (isIndexFile) {\r\n // Use foo.index (or deeper.path.index) instead of suffixing __2\r\n if (!acc[explicit]) {\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `⚠️ Key collision for \"${preferred}\" — using \"${explicit}\" for index file`,\r\n { existing: acc[preferred], incoming: full }\r\n );\r\n name = explicit;\r\n } else {\r\n // Extremely rare: even explicit collides (e.g. duplicate paths via symlinks)\r\n let i = 2;\r\n let next = `${explicit}__${i}`;\r\n while (acc[next]) {\r\n i += 1;\r\n next = `${explicit}__${i}`;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn(`⚠️ Key collision for \"${explicit}\" — using \"${next}\"`, {\r\n existing: acc[explicit],\r\n incoming: full,\r\n });\r\n name = next;\r\n }\r\n } else {\r\n // Non-index collision: suffix like original behavior\r\n let i = 2;\r\n let next = `${name}__${i}`;\r\n while (acc[next]) {\r\n i += 1;\r\n next = `${name}__${i}`;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn(`⚠️ Input key collision \"${name}\" -> using \"${next}\"`, {\r\n existing: acc[name],\r\n incoming: full,\r\n });\r\n name = next;\r\n }\r\n }\r\n\r\n acc[name] = full;\r\n }\r\n}\r\n\r\n/**\r\n * Discover integration pages/components and return a Rollup input map.\r\n *\r\n * @param srcRoot absolute or relative path to the source folder (e.g. \"resources/embed/ts\")\r\n * @param options\r\n * @returns Rollup input map: { [key]: absolutePath }\r\n */\r\nexport function generatePluginInputs(\r\n srcRoot: string = path.resolve(process.cwd(), \"ts\"),\r\n options: GeneratePluginInputsOptions = {}\r\n): PluginInputs {\r\n const {\r\n writeAppEntry = true,\r\n appEntryName = \"app.tsx\",\r\n includeAppEntryInInputs = true,\r\n appEntryKey = \"__app_entry\",\r\n verbose = true,\r\n } = options;\r\n\r\n const absRoot = path.resolve(srcRoot);\r\n const inputs: PluginInputs = {};\r\n\r\n const sets = makeIgnoreSets(options);\r\n const appEntryAbsPath = path.join(absRoot, appEntryName);\r\n\r\n // Crawl everything under absRoot (no folder assumptions)\r\n crawl(absRoot, absRoot, inputs, sets, appEntryAbsPath);\r\n\r\n if (verbose) {\r\n // eslint-disable-next-line no-console\r\n console.log(\"✅ Integrations discovered:\", inputs);\r\n }\r\n\r\n if (writeAppEntry) {\r\n writeAppEntryFile(inputs, absRoot, appEntryName);\r\n }\r\n\r\n if (!includeAppEntryInInputs) return inputs;\r\n\r\n return { ...inputs, [appEntryKey]: appEntryAbsPath };\r\n}"],"mappings":"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","names":["path","shouldInject","resolvePath","import_node_path","path"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -49,4 +49,55 @@ type FortiPrepOptions = FortiPrepTransformOptions & {
|
|
|
49
49
|
*/
|
|
50
50
|
declare function prep(options?: FortiPrepOptions): Plugin;
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
type PluginInputs = Record<string, string>;
|
|
53
|
+
type GeneratePluginInputsOptions = {
|
|
54
|
+
/**
|
|
55
|
+
* If true, also generates `app.tsx` that imports every discovered entry
|
|
56
|
+
* (handy for dev/HMR).
|
|
57
|
+
*
|
|
58
|
+
* Default: true
|
|
59
|
+
*/
|
|
60
|
+
writeAppEntry?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Name of the generated app entry file (inside srcRoot).
|
|
63
|
+
*
|
|
64
|
+
* Default: "app.tsx"
|
|
65
|
+
*/
|
|
66
|
+
appEntryName?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Adds the generated app entry to the returned Rollup inputs map.
|
|
69
|
+
*
|
|
70
|
+
* Default: true
|
|
71
|
+
*/
|
|
72
|
+
includeAppEntryInInputs?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Key name used for the generated app entry in Rollup inputs.
|
|
75
|
+
*
|
|
76
|
+
* Default: "__app_entry"
|
|
77
|
+
*/
|
|
78
|
+
appEntryKey?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Extra directory names to ignore (case-insensitive).
|
|
81
|
+
*/
|
|
82
|
+
ignoreDirs?: string[];
|
|
83
|
+
/**
|
|
84
|
+
* Extra “component-like” directory names to ignore (case-insensitive, exact match).
|
|
85
|
+
*/
|
|
86
|
+
componentLikeDirs?: string[];
|
|
87
|
+
/**
|
|
88
|
+
* Whether to print discovered inputs to console.
|
|
89
|
+
*
|
|
90
|
+
* Default: true
|
|
91
|
+
*/
|
|
92
|
+
verbose?: boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Discover integration pages/components and return a Rollup input map.
|
|
96
|
+
*
|
|
97
|
+
* @param srcRoot absolute or relative path to the source folder (e.g. "resources/embed/ts")
|
|
98
|
+
* @param options
|
|
99
|
+
* @returns Rollup input map: { [key]: absolutePath }
|
|
100
|
+
*/
|
|
101
|
+
declare function generatePluginInputs(srcRoot?: string, options?: GeneratePluginInputsOptions): PluginInputs;
|
|
102
|
+
|
|
103
|
+
export { type FortiPrepOptions, type FortiPrepTransformOptions, prep as default, generatePluginInputs as discoverEntrypoints, fortiPrepTransform };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,4 +49,55 @@ type FortiPrepOptions = FortiPrepTransformOptions & {
|
|
|
49
49
|
*/
|
|
50
50
|
declare function prep(options?: FortiPrepOptions): Plugin;
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
type PluginInputs = Record<string, string>;
|
|
53
|
+
type GeneratePluginInputsOptions = {
|
|
54
|
+
/**
|
|
55
|
+
* If true, also generates `app.tsx` that imports every discovered entry
|
|
56
|
+
* (handy for dev/HMR).
|
|
57
|
+
*
|
|
58
|
+
* Default: true
|
|
59
|
+
*/
|
|
60
|
+
writeAppEntry?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Name of the generated app entry file (inside srcRoot).
|
|
63
|
+
*
|
|
64
|
+
* Default: "app.tsx"
|
|
65
|
+
*/
|
|
66
|
+
appEntryName?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Adds the generated app entry to the returned Rollup inputs map.
|
|
69
|
+
*
|
|
70
|
+
* Default: true
|
|
71
|
+
*/
|
|
72
|
+
includeAppEntryInInputs?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Key name used for the generated app entry in Rollup inputs.
|
|
75
|
+
*
|
|
76
|
+
* Default: "__app_entry"
|
|
77
|
+
*/
|
|
78
|
+
appEntryKey?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Extra directory names to ignore (case-insensitive).
|
|
81
|
+
*/
|
|
82
|
+
ignoreDirs?: string[];
|
|
83
|
+
/**
|
|
84
|
+
* Extra “component-like” directory names to ignore (case-insensitive, exact match).
|
|
85
|
+
*/
|
|
86
|
+
componentLikeDirs?: string[];
|
|
87
|
+
/**
|
|
88
|
+
* Whether to print discovered inputs to console.
|
|
89
|
+
*
|
|
90
|
+
* Default: true
|
|
91
|
+
*/
|
|
92
|
+
verbose?: boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Discover integration pages/components and return a Rollup input map.
|
|
96
|
+
*
|
|
97
|
+
* @param srcRoot absolute or relative path to the source folder (e.g. "resources/embed/ts")
|
|
98
|
+
* @param options
|
|
99
|
+
* @returns Rollup input map: { [key]: absolutePath }
|
|
100
|
+
*/
|
|
101
|
+
declare function generatePluginInputs(srcRoot?: string, options?: GeneratePluginInputsOptions): PluginInputs;
|
|
102
|
+
|
|
103
|
+
export { type FortiPrepOptions, type FortiPrepTransformOptions, prep as default, generatePluginInputs as discoverEntrypoints, fortiPrepTransform };
|
package/dist/index.mjs
CHANGED
|
@@ -55,12 +55,12 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
55
55
|
return {
|
|
56
56
|
name: "fortiplugin-prep/transform",
|
|
57
57
|
visitor: {
|
|
58
|
-
ImportDeclaration(
|
|
59
|
-
const node =
|
|
58
|
+
ImportDeclaration(path2) {
|
|
59
|
+
const node = path2.node;
|
|
60
60
|
const importId = node.source.value;
|
|
61
61
|
if (!shouldInject(importId, opts)) {
|
|
62
62
|
keptImports.push(node);
|
|
63
|
-
|
|
63
|
+
path2.remove();
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
for (const s of node.specifiers) {
|
|
@@ -76,23 +76,23 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
path2.remove();
|
|
80
80
|
},
|
|
81
|
-
ExportDefaultDeclaration(
|
|
82
|
-
const decl =
|
|
81
|
+
ExportDefaultDeclaration(path2) {
|
|
82
|
+
const decl = path2.node.declaration;
|
|
83
83
|
if (t.isIdentifier(decl)) {
|
|
84
84
|
defaultExportLocalName = decl.name;
|
|
85
|
-
|
|
85
|
+
path2.remove();
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
const id =
|
|
89
|
-
|
|
88
|
+
const id = path2.scope.generateUidIdentifier("defaultExport");
|
|
89
|
+
path2.replaceWith(
|
|
90
90
|
t.variableDeclaration("const", [t.variableDeclarator(id, decl)])
|
|
91
91
|
);
|
|
92
92
|
defaultExportLocalName = id.name;
|
|
93
93
|
},
|
|
94
|
-
ExportNamedDeclaration(
|
|
95
|
-
const node =
|
|
94
|
+
ExportNamedDeclaration(path2) {
|
|
95
|
+
const node = path2.node;
|
|
96
96
|
keptNamedExports.push(node);
|
|
97
97
|
if (node.specifiers?.length) {
|
|
98
98
|
let foundExplicitDefault = false;
|
|
@@ -115,13 +115,13 @@ function fortiPrepTransform(_api, rawOpts = {}) {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
path2.remove();
|
|
119
119
|
},
|
|
120
120
|
Program: {
|
|
121
|
-
exit(
|
|
122
|
-
const program =
|
|
121
|
+
exit(path2) {
|
|
122
|
+
const program = path2.node;
|
|
123
123
|
if (!defaultExportLocalName) {
|
|
124
|
-
throw
|
|
124
|
+
throw path2.buildCodeFrameError(DEFAULT_EXPORT_ERROR);
|
|
125
125
|
}
|
|
126
126
|
const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);
|
|
127
127
|
const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;
|
|
@@ -302,8 +302,157 @@ function prep(options = {}) {
|
|
|
302
302
|
}
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
|
+
|
|
306
|
+
// src/utils/generate-plugin-inputs.ts
|
|
307
|
+
import path from "path";
|
|
308
|
+
import * as fs from "fs";
|
|
309
|
+
var EXT_PATTERN = /\.(tsx?|jsx?)$/i;
|
|
310
|
+
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
311
|
+
"node_modules",
|
|
312
|
+
".git",
|
|
313
|
+
".vite",
|
|
314
|
+
".internal",
|
|
315
|
+
"dist",
|
|
316
|
+
"build",
|
|
317
|
+
"public"
|
|
318
|
+
]);
|
|
319
|
+
var DEFAULT_COMPONENT_LIKE_DIRS = /* @__PURE__ */ new Set([
|
|
320
|
+
"component",
|
|
321
|
+
"components",
|
|
322
|
+
"ui",
|
|
323
|
+
"uis",
|
|
324
|
+
"widget",
|
|
325
|
+
"widgets",
|
|
326
|
+
"atom",
|
|
327
|
+
"atoms",
|
|
328
|
+
"molecule",
|
|
329
|
+
"molecules",
|
|
330
|
+
"organism",
|
|
331
|
+
"organisms",
|
|
332
|
+
"layout",
|
|
333
|
+
"layouts",
|
|
334
|
+
"partial",
|
|
335
|
+
"partials"
|
|
336
|
+
]);
|
|
337
|
+
function normalizeName(x) {
|
|
338
|
+
return String(x ?? "").toLowerCase();
|
|
339
|
+
}
|
|
340
|
+
function makeIgnoreSets(opts) {
|
|
341
|
+
const ignoreDirs = new Set(DEFAULT_IGNORE_DIRS);
|
|
342
|
+
const componentLikeDirs = new Set(DEFAULT_COMPONENT_LIKE_DIRS);
|
|
343
|
+
for (const d of opts?.ignoreDirs ?? []) ignoreDirs.add(normalizeName(d));
|
|
344
|
+
for (const d of opts?.componentLikeDirs ?? []) componentLikeDirs.add(normalizeName(d));
|
|
345
|
+
return { ignoreDirs, componentLikeDirs };
|
|
346
|
+
}
|
|
347
|
+
function isIgnoredDir(dirName, sets) {
|
|
348
|
+
const name = normalizeName(dirName);
|
|
349
|
+
return sets.ignoreDirs.has(name) || sets.componentLikeDirs.has(name);
|
|
350
|
+
}
|
|
351
|
+
function writeAppEntryFile(inputs, srcRoot, appEntryName) {
|
|
352
|
+
const app = path.join(srcRoot, appEntryName);
|
|
353
|
+
const lines = ["// Auto-generated \u2013 do not edit", ""];
|
|
354
|
+
const entries = Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b));
|
|
355
|
+
for (const [name, full] of entries) {
|
|
356
|
+
const rel = "./" + path.relative(srcRoot, full).replace(/\\/g, "/").replace(EXT_PATTERN, "");
|
|
357
|
+
const variable = name.replace(/[^a-zA-Z0-9_$]/g, "_").replace(/^(\d)/, "_$1");
|
|
358
|
+
lines.push(`import * as ${variable} from '${rel}';`);
|
|
359
|
+
lines.push(`console.log('${name} loaded:', ${variable});`, "");
|
|
360
|
+
}
|
|
361
|
+
fs.writeFileSync(app, lines.join("\n"), "utf8");
|
|
362
|
+
console.log(`\u2705 Generated ${appEntryName} in ${srcRoot}`);
|
|
363
|
+
}
|
|
364
|
+
function pathToKey(relNoExt, opts) {
|
|
365
|
+
let normalized = relNoExt.replace(/\\/g, "/");
|
|
366
|
+
if (opts.collapseIndex) {
|
|
367
|
+
normalized = normalized.replace(/\/index$/i, "");
|
|
368
|
+
}
|
|
369
|
+
let key = normalized.split("/").filter(Boolean).join(".");
|
|
370
|
+
if (!key) key = "index";
|
|
371
|
+
return key;
|
|
372
|
+
}
|
|
373
|
+
function crawl(dirPath, baseDir, acc, sets, appEntryAbsPath) {
|
|
374
|
+
if (!fs.existsSync(dirPath)) return;
|
|
375
|
+
for (const item of fs.readdirSync(dirPath)) {
|
|
376
|
+
const full = path.join(dirPath, item);
|
|
377
|
+
const stat = fs.statSync(full);
|
|
378
|
+
if (stat.isDirectory()) {
|
|
379
|
+
if (isIgnoredDir(item, sets)) continue;
|
|
380
|
+
crawl(full, baseDir, acc, sets, appEntryAbsPath);
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (!EXT_PATTERN.test(item)) continue;
|
|
384
|
+
if (path.resolve(full) === path.resolve(appEntryAbsPath)) {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const relNoExt = path.relative(baseDir, full).replace(EXT_PATTERN, "");
|
|
388
|
+
const isIndexFile = /(^|[\\/])index$/i.test(relNoExt);
|
|
389
|
+
const preferred = pathToKey(relNoExt, { collapseIndex: true });
|
|
390
|
+
const explicit = pathToKey(relNoExt, { collapseIndex: false });
|
|
391
|
+
let name = preferred;
|
|
392
|
+
const existing = acc[name];
|
|
393
|
+
if (existing && path.resolve(existing) !== path.resolve(full)) {
|
|
394
|
+
if (isIndexFile) {
|
|
395
|
+
if (!acc[explicit]) {
|
|
396
|
+
console.warn(
|
|
397
|
+
`\u26A0\uFE0F Key collision for "${preferred}" \u2014 using "${explicit}" for index file`,
|
|
398
|
+
{ existing: acc[preferred], incoming: full }
|
|
399
|
+
);
|
|
400
|
+
name = explicit;
|
|
401
|
+
} else {
|
|
402
|
+
let i = 2;
|
|
403
|
+
let next = `${explicit}__${i}`;
|
|
404
|
+
while (acc[next]) {
|
|
405
|
+
i += 1;
|
|
406
|
+
next = `${explicit}__${i}`;
|
|
407
|
+
}
|
|
408
|
+
console.warn(`\u26A0\uFE0F Key collision for "${explicit}" \u2014 using "${next}"`, {
|
|
409
|
+
existing: acc[explicit],
|
|
410
|
+
incoming: full
|
|
411
|
+
});
|
|
412
|
+
name = next;
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
let i = 2;
|
|
416
|
+
let next = `${name}__${i}`;
|
|
417
|
+
while (acc[next]) {
|
|
418
|
+
i += 1;
|
|
419
|
+
next = `${name}__${i}`;
|
|
420
|
+
}
|
|
421
|
+
console.warn(`\u26A0\uFE0F Input key collision "${name}" -> using "${next}"`, {
|
|
422
|
+
existing: acc[name],
|
|
423
|
+
incoming: full
|
|
424
|
+
});
|
|
425
|
+
name = next;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
acc[name] = full;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function generatePluginInputs(srcRoot = path.resolve(process.cwd(), "ts"), options = {}) {
|
|
432
|
+
const {
|
|
433
|
+
writeAppEntry = true,
|
|
434
|
+
appEntryName = "app.tsx",
|
|
435
|
+
includeAppEntryInInputs = true,
|
|
436
|
+
appEntryKey = "__app_entry",
|
|
437
|
+
verbose = true
|
|
438
|
+
} = options;
|
|
439
|
+
const absRoot = path.resolve(srcRoot);
|
|
440
|
+
const inputs = {};
|
|
441
|
+
const sets = makeIgnoreSets(options);
|
|
442
|
+
const appEntryAbsPath = path.join(absRoot, appEntryName);
|
|
443
|
+
crawl(absRoot, absRoot, inputs, sets, appEntryAbsPath);
|
|
444
|
+
if (verbose) {
|
|
445
|
+
console.log("\u2705 Integrations discovered:", inputs);
|
|
446
|
+
}
|
|
447
|
+
if (writeAppEntry) {
|
|
448
|
+
writeAppEntryFile(inputs, absRoot, appEntryName);
|
|
449
|
+
}
|
|
450
|
+
if (!includeAppEntryInInputs) return inputs;
|
|
451
|
+
return { ...inputs, [appEntryKey]: appEntryAbsPath };
|
|
452
|
+
}
|
|
305
453
|
export {
|
|
306
454
|
prep as default,
|
|
455
|
+
generatePluginInputs as discoverEntrypoints,
|
|
307
456
|
fortiPrepTransform
|
|
308
457
|
};
|
|
309
458
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vite/prep.ts","../src/babel/transform.ts"],"sourcesContent":["import { transformSync } from \"@babel/core\";\r\nimport { readFileSync, writeFileSync } from \"node:fs\";\r\nimport { dirname, resolve as resolvePath } from \"node:path\";\r\nimport type {NormalizedOutputOptions, OutputBundle, OutputOptions} from \"rollup\";\r\nimport type { Plugin as VitePlugin } from \"vite\";\r\n\r\nimport fortiPrepTransform, {\r\n type FortiPrepTransformOptions,\r\n} from \"../babel/transform\";\r\n\r\nexport type FortiPrepOptions = FortiPrepTransformOptions & {\r\n /**\r\n * Which emitted entry file extensions should be rewritten.\r\n * Default: [\".js\", \".mjs\"]\r\n */\r\n entryExtensions?: string[];\r\n\r\n /**\r\n * Vite plugin name\r\n * Default: \"fortiplugin-prep\"\r\n */\r\n pluginName?: string;\r\n};\r\n\r\nconst DEFAULT_INJECTED_IDS = [\"react\", \"react/jsx-runtime\"] as const;\r\nconst DEFAULT_INJECTED_PREFIXES = [\"@inertiajs/\", \"@host/\"] as const;\r\n\r\nfunction resolveOutDir(outputOptions: OutputOptions): string | null {\r\n if (outputOptions.dir) return outputOptions.dir;\r\n if (outputOptions.file) return dirname(outputOptions.file);\r\n return null;\r\n}\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * FortiPlugin bundle adapter:\r\n * - marks injected imports as Rollup externals (so they survive into output)\r\n * - rewrites built entry chunks to remove those imports and load them from runtime deps\r\n */\r\nexport default function prep(options: FortiPrepOptions = {}): VitePlugin {\r\n const injectedIds = options.injectedIds ?? [...DEFAULT_INJECTED_IDS];\r\n const injectedPrefixes = options.injectedPrefixes ?? [...DEFAULT_INJECTED_PREFIXES];\r\n\r\n const runtimeKey = options.runtimeKey ?? \"imports\";\r\n const depsParam = options.depsParam ?? \"deps\";\r\n\r\n const entryExtensions = options.entryExtensions ?? [\".js\", \".mjs\"];\r\n const pluginName = options.pluginName ?? \"fortiplugin-prep\";\r\n\r\n const transformOptions: FortiPrepTransformOptions = {\r\n injectedIds,\r\n injectedPrefixes,\r\n runtimeKey,\r\n depsParam,\r\n };\r\n\r\n return {\r\n name: pluginName,\r\n apply: \"build\",\r\n\r\n config() {\r\n return {\r\n define: {\r\n \"process.env.NODE_ENV\": '\"production\"',\r\n },\r\n build: {\r\n rollupOptions: {\r\n // Ensure virtual imports don't need to resolve.\r\n external: (id: string) => shouldInject(id, transformOptions),\r\n },\r\n },\r\n };\r\n },\r\n\r\n writeBundle(outputOptions: NormalizedOutputOptions, bundle: OutputBundle) {\r\n const outDir = resolveOutDir(outputOptions);\r\n if (!outDir) return;\r\n\r\n for (const [fileName, item] of Object.entries(bundle)) {\r\n if (item.type !== \"chunk\") continue;\r\n if (!item.isEntry) continue;\r\n\r\n if (!entryExtensions.some((ext) => fileName.endsWith(ext))) continue;\r\n\r\n const absPath = resolvePath(outDir, fileName);\r\n const input = readFileSync(absPath, \"utf-8\");\r\n\r\n const result = transformSync(input, {\r\n filename: absPath,\r\n sourceType: \"module\",\r\n // Fresh plugin instance per file (Babel calls plugin factory per file when passed as [fn, opts])\r\n plugins: [[fortiPrepTransform as any, transformOptions]],\r\n generatorOpts: {\r\n compact: false,\r\n comments: true,\r\n retainLines: false,\r\n },\r\n });\r\n\r\n if (!result?.code) continue;\r\n writeFileSync(absPath, result.code, \"utf-8\");\r\n }\r\n },\r\n };\r\n}","// noinspection JSUnusedGlobalSymbols,GrazieInspection\r\n\r\nimport type {PluginObj} from \"@babel/core\";\r\nimport * as t from \"@babel/types\";\r\nimport type {NodePath} from \"@babel/traverse\";\r\n\r\nexport type FortiPrepTransformOptions = {\r\n /**\r\n * Exact import ids to inject (removed from bundle and loaded from runtime deps).\r\n * Example: [\"react\", \"react/jsx-runtime\", \"@host/ui\"]\r\n */\r\n injectedIds?: string[];\r\n\r\n /**\r\n * Prefix import ids to inject.\r\n * Example: [\"@host/\", \"@inertiajs/\"]\r\n */\r\n injectedPrefixes?: string[];\r\n\r\n /**\r\n * The key on the deps object used as the import map.\r\n * Wrapper supports passing deps.imports OR passing the import map directly.\r\n *\r\n * Default: \"imports\"\r\n */\r\n runtimeKey?: string;\r\n\r\n /**\r\n * Wrapper function parameter name.\r\n * Default: \"deps\"\r\n */\r\n depsParam?: string;\r\n};\r\n\r\nconst DEFAULTS: Required<Pick<FortiPrepTransformOptions, \"runtimeKey\" | \"depsParam\">> = {\r\n runtimeKey: \"imports\",\r\n depsParam: \"deps\",\r\n};\r\n\r\nconst DEFAULT_EXPORT_ERROR =\r\n \"PROBLEM!!, No known default function was found, your code either possesses NO named default export or this export format is currently not supported.\";\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\ntype CapturedImport =\r\n | { kind: \"default\"; local: string }\r\n | { kind: \"namespace\"; local: string }\r\n | { kind: \"named\"; imported: string; local: string };\r\n\r\nfunction getImportedName(spec: t.ImportSpecifier): string {\r\n return t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;\r\n}\r\n\r\nfunction makeImportMapExpr(\r\n depsIdent: t.Identifier,\r\n runtimeKey: string\r\n): t.Expression {\r\n // Support both:\r\n // factory({ imports: { ... } })\r\n // and:\r\n // factory({ ... }) // direct import map\r\n //\r\n // const __imports =\r\n // deps && typeof deps === \"object\" && \"imports\" in deps\r\n // ? deps.imports\r\n // : (deps ?? {});\r\n const hasKey = t.binaryExpression(\r\n \"in\",\r\n t.stringLiteral(runtimeKey),\r\n depsIdent\r\n );\r\n\r\n const isObj = t.logicalExpression(\r\n \"&&\",\r\n t.binaryExpression(\"!==\", depsIdent, t.nullLiteral()),\r\n t.binaryExpression(\"===\", t.unaryExpression(\"typeof\", depsIdent), t.stringLiteral(\"object\"))\r\n );\r\n\r\n const test = t.logicalExpression(\"&&\", isObj, hasKey);\r\n\r\n const depsKey = t.memberExpression(depsIdent, t.identifier(runtimeKey));\r\n const fallback = t.logicalExpression(\"||\", depsIdent, t.objectExpression([]));\r\n\r\n return t.conditionalExpression(test, depsKey, fallback);\r\n}\r\n\r\n/**\r\n * Babel plugin factory (Babel calls this per-file when used as `[plugin, options]`).\r\n */\r\nexport default function fortiPrepTransform(\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n _api: unknown,\r\n rawOpts: FortiPrepTransformOptions = {}\r\n): PluginObj {\r\n const opts: FortiPrepTransformOptions = {\r\n ...rawOpts,\r\n runtimeKey: rawOpts.runtimeKey ?? DEFAULTS.runtimeKey,\r\n depsParam: rawOpts.depsParam ?? DEFAULTS.depsParam,\r\n };\r\n\r\n // per-file state (because Babel calls the plugin per file)\r\n const keptImports: t.ImportDeclaration[] = [];\r\n const keptNamedExports: t.ExportNamedDeclaration[] = [];\r\n\r\n const injectedImportsById = new Map<string, CapturedImport[]>();\r\n\r\n let defaultExportLocalName: string | null = null;\r\n let returnDefaultProperty = false;\r\n\r\n function captureImport(importId: string, entry: CapturedImport) {\r\n const list = injectedImportsById.get(importId) ?? [];\r\n list.push(entry);\r\n injectedImportsById.set(importId, list);\r\n }\r\n\r\n return {\r\n name: \"fortiplugin-prep/transform\",\r\n visitor: {\r\n ImportDeclaration(path: NodePath<t.ImportDeclaration>) {\r\n const node = path.node;\r\n const importId = node.source.value;\r\n\r\n if (!shouldInject(importId, opts)) {\r\n keptImports.push(node);\r\n path.remove();\r\n return;\r\n }\r\n\r\n // Remove injected import and capture its specifiers to recreate inside wrapper.\r\n for (const s of node.specifiers) {\r\n if (t.isImportDefaultSpecifier(s)) {\r\n captureImport(importId, {kind: \"default\", local: s.local.name});\r\n } else if (t.isImportNamespaceSpecifier(s)) {\r\n captureImport(importId, {kind: \"namespace\", local: s.local.name});\r\n } else if (t.isImportSpecifier(s)) {\r\n captureImport(importId, {\r\n kind: \"named\",\r\n imported: getImportedName(s),\r\n local: s.local.name,\r\n });\r\n }\r\n }\r\n\r\n // side-effect only imports (import \"@host/ui\") become no-ops at runtime\r\n path.remove();\r\n },\r\n\r\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\r\n const decl = path.node.declaration;\r\n\r\n // export default Foo;\r\n if (t.isIdentifier(decl)) {\r\n defaultExportLocalName = decl.name;\r\n path.remove();\r\n return;\r\n }\r\n\r\n // export default (expr/anon fn/class)\r\n // Hoist into a const (inside wrapper) so we can `return <id>`\r\n const id = path.scope.generateUidIdentifier(\"defaultExport\");\r\n path.replaceWith(\r\n t.variableDeclaration(\"const\", [t.variableDeclarator(id, decl as any)])\r\n );\r\n defaultExportLocalName = id.name;\r\n },\r\n\r\n ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {\r\n const node = path.node;\r\n keptNamedExports.push(node);\r\n\r\n // Detect Rollup-style: export { Foo as default }\r\n if (node.specifiers?.length) {\r\n let foundExplicitDefault = false;\r\n\r\n node.specifiers = node.specifiers.filter((spec) => {\r\n const exported =\r\n t.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value;\r\n\r\n if (exported === \"default\") {\r\n const local = (spec as any)?.local?.name as string | undefined;\r\n if (local) defaultExportLocalName = local;\r\n foundExplicitDefault = true;\r\n return false; // remove\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Minified fallback behavior:\r\n // If no default specifier found and exactly one spec exists,\r\n // treat it as the container and return `<local>.default`.\r\n if (!foundExplicitDefault && !defaultExportLocalName && node.specifiers.length === 1) {\r\n const only = node.specifiers[0] as any;\r\n if (only?.local?.name) {\r\n defaultExportLocalName = only.local.name;\r\n returnDefaultProperty = true;\r\n node.specifiers = [];\r\n }\r\n }\r\n }\r\n\r\n path.remove();\r\n },\r\n\r\n Program: {\r\n exit(path: NodePath<t.Program>) {\r\n const program = path.node;\r\n\r\n if (!defaultExportLocalName) {\r\n throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);\r\n }\r\n\r\n const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);\r\n const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;\r\n\r\n // const __imports = (deps has runtimeKey) ? deps[runtimeKey] : (deps || {});\r\n const importsIdent = t.identifier(\"__imports\");\r\n const importsInit = makeImportMapExpr(depsIdent, runtimeKey);\r\n const importsDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(importsIdent, importsInit),\r\n ]);\r\n\r\n // helper:\r\n // const __default = (m) => (m && typeof m === \"object\" && \"default\" in m ? m.default : m);\r\n const defaultHelperIdent = t.identifier(\"__default\");\r\n const defaultHelperDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n defaultHelperIdent,\r\n t.arrowFunctionExpression(\r\n [t.identifier(\"m\")],\r\n t.conditionalExpression(\r\n t.logicalExpression(\r\n \"&&\",\r\n t.logicalExpression(\r\n \"&&\",\r\n t.identifier(\"m\"),\r\n t.binaryExpression(\r\n \"===\",\r\n t.unaryExpression(\"typeof\", t.identifier(\"m\")),\r\n t.stringLiteral(\"object\")\r\n )\r\n ),\r\n t.binaryExpression(\"in\", t.stringLiteral(\"default\"), t.identifier(\"m\"))\r\n ),\r\n t.memberExpression(t.identifier(\"m\"), t.identifier(\"default\")),\r\n t.identifier(\"m\")\r\n )\r\n )\r\n ),\r\n ]);\r\n\r\n // Build injected module locals inside wrapper\r\n const injectedStmts: t.Statement[] = [importsDecl, defaultHelperDecl];\r\n\r\n for (const [importId, specs] of injectedImportsById.entries()) {\r\n const modIdent = t.identifier(\r\n `__m_${importId.replace(/[^a-zA-Z0-9_$]/g, \"_\")}`\r\n );\r\n\r\n // const __m_xxx = __imports[\"<importId>\"];\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n modIdent,\r\n t.memberExpression(importsIdent, t.stringLiteral(importId), true)\r\n ),\r\n ])\r\n );\r\n\r\n const named: Array<{ imported: string; local: string }> = [];\r\n\r\n for (const s of specs) {\r\n if (s.kind === \"default\") {\r\n // const Local = __default(__m_xxx);\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.identifier(s.local),\r\n t.callExpression(defaultHelperIdent, [modIdent])\r\n ),\r\n ])\r\n );\r\n } else if (s.kind === \"namespace\") {\r\n // const Local = __m_xxx;\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(t.identifier(s.local), modIdent),\r\n ])\r\n );\r\n } else {\r\n named.push({imported: s.imported, local: s.local});\r\n }\r\n }\r\n\r\n if (named.length) {\r\n // const { A, B: C } = (__m_xxx ?? {});\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.objectPattern(\r\n named.map(({imported, local}) =>\r\n t.objectProperty(\r\n t.identifier(imported),\r\n t.identifier(local),\r\n false,\r\n imported === local\r\n )\r\n )\r\n ),\r\n t.logicalExpression(\"||\", modIdent, t.objectExpression([]))\r\n ),\r\n ])\r\n );\r\n }\r\n }\r\n\r\n const returnExpr = returnDefaultProperty\r\n ? t.memberExpression(\r\n t.identifier(defaultExportLocalName),\r\n t.identifier(\"default\")\r\n )\r\n : t.identifier(defaultExportLocalName);\r\n\r\n // Wrapper body:\r\n // injectedStmts...\r\n // <original body>\r\n // return <defaultExport>\r\n const wrapperBody: t.Statement[] = [];\r\n wrapperBody.push(...injectedStmts);\r\n wrapperBody.push(...program.body);\r\n wrapperBody.push(t.returnStatement(returnExpr));\r\n\r\n const wrapper = t.exportDefaultDeclaration(\r\n t.functionDeclaration(\r\n null,\r\n [depsIdent],\r\n t.blockStatement(wrapperBody)\r\n )\r\n );\r\n\r\n // Final program:\r\n // kept imports at module scope\r\n // export default function(deps) { ... }\r\n // kept named exports (same as your old behavior)\r\n program.body = [...keptImports, wrapper, ...keptNamedExports] as any;\r\n },\r\n },\r\n },\r\n };\r\n}"],"mappings":"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","names":["shouldInject"]}
|
|
1
|
+
{"version":3,"sources":["../src/vite/prep.ts","../src/babel/transform.ts","../src/utils/generate-plugin-inputs.ts"],"sourcesContent":["import { transformSync } from \"@babel/core\";\r\nimport { readFileSync, writeFileSync } from \"node:fs\";\r\nimport { dirname, resolve as resolvePath } from \"node:path\";\r\nimport type {NormalizedOutputOptions, OutputBundle, OutputOptions} from \"rollup\";\r\nimport type { Plugin as VitePlugin } from \"vite\";\r\n\r\nimport fortiPrepTransform, {\r\n type FortiPrepTransformOptions,\r\n} from \"../babel/transform\";\r\n\r\nexport type FortiPrepOptions = FortiPrepTransformOptions & {\r\n /**\r\n * Which emitted entry file extensions should be rewritten.\r\n * Default: [\".js\", \".mjs\"]\r\n */\r\n entryExtensions?: string[];\r\n\r\n /**\r\n * Vite plugin name\r\n * Default: \"fortiplugin-prep\"\r\n */\r\n pluginName?: string;\r\n};\r\n\r\nconst DEFAULT_INJECTED_IDS = [\"react\", \"react/jsx-runtime\"] as const;\r\nconst DEFAULT_INJECTED_PREFIXES = [\"@inertiajs/\", \"@host/\"] as const;\r\n\r\nfunction resolveOutDir(outputOptions: OutputOptions): string | null {\r\n if (outputOptions.dir) return outputOptions.dir;\r\n if (outputOptions.file) return dirname(outputOptions.file);\r\n return null;\r\n}\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * FortiPlugin bundle adapter:\r\n * - marks injected imports as Rollup externals (so they survive into output)\r\n * - rewrites built entry chunks to remove those imports and load them from runtime deps\r\n */\r\nexport default function prep(options: FortiPrepOptions = {}): VitePlugin {\r\n const injectedIds = options.injectedIds ?? [...DEFAULT_INJECTED_IDS];\r\n const injectedPrefixes = options.injectedPrefixes ?? [...DEFAULT_INJECTED_PREFIXES];\r\n\r\n const runtimeKey = options.runtimeKey ?? \"imports\";\r\n const depsParam = options.depsParam ?? \"deps\";\r\n\r\n const entryExtensions = options.entryExtensions ?? [\".js\", \".mjs\"];\r\n const pluginName = options.pluginName ?? \"fortiplugin-prep\";\r\n\r\n const transformOptions: FortiPrepTransformOptions = {\r\n injectedIds,\r\n injectedPrefixes,\r\n runtimeKey,\r\n depsParam,\r\n };\r\n\r\n return {\r\n name: pluginName,\r\n apply: \"build\",\r\n\r\n config() {\r\n return {\r\n define: {\r\n \"process.env.NODE_ENV\": '\"production\"',\r\n },\r\n build: {\r\n rollupOptions: {\r\n // Ensure virtual imports don't need to resolve.\r\n external: (id: string) => shouldInject(id, transformOptions),\r\n },\r\n },\r\n };\r\n },\r\n\r\n writeBundle(outputOptions: NormalizedOutputOptions, bundle: OutputBundle) {\r\n const outDir = resolveOutDir(outputOptions);\r\n if (!outDir) return;\r\n\r\n for (const [fileName, item] of Object.entries(bundle)) {\r\n if (item.type !== \"chunk\") continue;\r\n if (!item.isEntry) continue;\r\n\r\n if (!entryExtensions.some((ext) => fileName.endsWith(ext))) continue;\r\n\r\n const absPath = resolvePath(outDir, fileName);\r\n const input = readFileSync(absPath, \"utf-8\");\r\n\r\n const result = transformSync(input, {\r\n filename: absPath,\r\n sourceType: \"module\",\r\n // Fresh plugin instance per file (Babel calls plugin factory per file when passed as [fn, opts])\r\n plugins: [[fortiPrepTransform as any, transformOptions]],\r\n generatorOpts: {\r\n compact: false,\r\n comments: true,\r\n retainLines: false,\r\n },\r\n });\r\n\r\n if (!result?.code) continue;\r\n writeFileSync(absPath, result.code, \"utf-8\");\r\n }\r\n },\r\n };\r\n}","// noinspection JSUnusedGlobalSymbols,GrazieInspection\r\n\r\nimport type {PluginObj} from \"@babel/core\";\r\nimport * as t from \"@babel/types\";\r\nimport type {NodePath} from \"@babel/traverse\";\r\n\r\nexport type FortiPrepTransformOptions = {\r\n /**\r\n * Exact import ids to inject (removed from bundle and loaded from runtime deps).\r\n * Example: [\"react\", \"react/jsx-runtime\", \"@host/ui\"]\r\n */\r\n injectedIds?: string[];\r\n\r\n /**\r\n * Prefix import ids to inject.\r\n * Example: [\"@host/\", \"@inertiajs/\"]\r\n */\r\n injectedPrefixes?: string[];\r\n\r\n /**\r\n * The key on the deps object used as the import map.\r\n * Wrapper supports passing deps.imports OR passing the import map directly.\r\n *\r\n * Default: \"imports\"\r\n */\r\n runtimeKey?: string;\r\n\r\n /**\r\n * Wrapper function parameter name.\r\n * Default: \"deps\"\r\n */\r\n depsParam?: string;\r\n};\r\n\r\nconst DEFAULTS: Required<Pick<FortiPrepTransformOptions, \"runtimeKey\" | \"depsParam\">> = {\r\n runtimeKey: \"imports\",\r\n depsParam: \"deps\",\r\n};\r\n\r\nconst DEFAULT_EXPORT_ERROR =\r\n \"PROBLEM!!, No known default function was found, your code either possesses NO named default export or this export format is currently not supported.\";\r\n\r\nfunction shouldInject(id: string, opts: FortiPrepTransformOptions): boolean {\r\n const ids = opts.injectedIds ?? [];\r\n const prefixes = opts.injectedPrefixes ?? [];\r\n if (ids.includes(id)) return true;\r\n for (const p of prefixes) if (id.startsWith(p)) return true;\r\n return false;\r\n}\r\n\r\ntype CapturedImport =\r\n | { kind: \"default\"; local: string }\r\n | { kind: \"namespace\"; local: string }\r\n | { kind: \"named\"; imported: string; local: string };\r\n\r\nfunction getImportedName(spec: t.ImportSpecifier): string {\r\n return t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;\r\n}\r\n\r\nfunction makeImportMapExpr(\r\n depsIdent: t.Identifier,\r\n runtimeKey: string\r\n): t.Expression {\r\n // Support both:\r\n // factory({ imports: { ... } })\r\n // and:\r\n // factory({ ... }) // direct import map\r\n //\r\n // const __imports =\r\n // deps && typeof deps === \"object\" && \"imports\" in deps\r\n // ? deps.imports\r\n // : (deps ?? {});\r\n const hasKey = t.binaryExpression(\r\n \"in\",\r\n t.stringLiteral(runtimeKey),\r\n depsIdent\r\n );\r\n\r\n const isObj = t.logicalExpression(\r\n \"&&\",\r\n t.binaryExpression(\"!==\", depsIdent, t.nullLiteral()),\r\n t.binaryExpression(\"===\", t.unaryExpression(\"typeof\", depsIdent), t.stringLiteral(\"object\"))\r\n );\r\n\r\n const test = t.logicalExpression(\"&&\", isObj, hasKey);\r\n\r\n const depsKey = t.memberExpression(depsIdent, t.identifier(runtimeKey));\r\n const fallback = t.logicalExpression(\"||\", depsIdent, t.objectExpression([]));\r\n\r\n return t.conditionalExpression(test, depsKey, fallback);\r\n}\r\n\r\n/**\r\n * Babel plugin factory (Babel calls this per-file when used as `[plugin, options]`).\r\n */\r\nexport default function fortiPrepTransform(\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n _api: unknown,\r\n rawOpts: FortiPrepTransformOptions = {}\r\n): PluginObj {\r\n const opts: FortiPrepTransformOptions = {\r\n ...rawOpts,\r\n runtimeKey: rawOpts.runtimeKey ?? DEFAULTS.runtimeKey,\r\n depsParam: rawOpts.depsParam ?? DEFAULTS.depsParam,\r\n };\r\n\r\n // per-file state (because Babel calls the plugin per file)\r\n const keptImports: t.ImportDeclaration[] = [];\r\n const keptNamedExports: t.ExportNamedDeclaration[] = [];\r\n\r\n const injectedImportsById = new Map<string, CapturedImport[]>();\r\n\r\n let defaultExportLocalName: string | null = null;\r\n let returnDefaultProperty = false;\r\n\r\n function captureImport(importId: string, entry: CapturedImport) {\r\n const list = injectedImportsById.get(importId) ?? [];\r\n list.push(entry);\r\n injectedImportsById.set(importId, list);\r\n }\r\n\r\n return {\r\n name: \"fortiplugin-prep/transform\",\r\n visitor: {\r\n ImportDeclaration(path: NodePath<t.ImportDeclaration>) {\r\n const node = path.node;\r\n const importId = node.source.value;\r\n\r\n if (!shouldInject(importId, opts)) {\r\n keptImports.push(node);\r\n path.remove();\r\n return;\r\n }\r\n\r\n // Remove injected import and capture its specifiers to recreate inside wrapper.\r\n for (const s of node.specifiers) {\r\n if (t.isImportDefaultSpecifier(s)) {\r\n captureImport(importId, {kind: \"default\", local: s.local.name});\r\n } else if (t.isImportNamespaceSpecifier(s)) {\r\n captureImport(importId, {kind: \"namespace\", local: s.local.name});\r\n } else if (t.isImportSpecifier(s)) {\r\n captureImport(importId, {\r\n kind: \"named\",\r\n imported: getImportedName(s),\r\n local: s.local.name,\r\n });\r\n }\r\n }\r\n\r\n // side-effect only imports (import \"@host/ui\") become no-ops at runtime\r\n path.remove();\r\n },\r\n\r\n ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {\r\n const decl = path.node.declaration;\r\n\r\n // export default Foo;\r\n if (t.isIdentifier(decl)) {\r\n defaultExportLocalName = decl.name;\r\n path.remove();\r\n return;\r\n }\r\n\r\n // export default (expr/anon fn/class)\r\n // Hoist into a const (inside wrapper) so we can `return <id>`\r\n const id = path.scope.generateUidIdentifier(\"defaultExport\");\r\n path.replaceWith(\r\n t.variableDeclaration(\"const\", [t.variableDeclarator(id, decl as any)])\r\n );\r\n defaultExportLocalName = id.name;\r\n },\r\n\r\n ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {\r\n const node = path.node;\r\n keptNamedExports.push(node);\r\n\r\n // Detect Rollup-style: export { Foo as default }\r\n if (node.specifiers?.length) {\r\n let foundExplicitDefault = false;\r\n\r\n node.specifiers = node.specifiers.filter((spec) => {\r\n const exported =\r\n t.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value;\r\n\r\n if (exported === \"default\") {\r\n const local = (spec as any)?.local?.name as string | undefined;\r\n if (local) defaultExportLocalName = local;\r\n foundExplicitDefault = true;\r\n return false; // remove\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Minified fallback behavior:\r\n // If no default specifier found and exactly one spec exists,\r\n // treat it as the container and return `<local>.default`.\r\n if (!foundExplicitDefault && !defaultExportLocalName && node.specifiers.length === 1) {\r\n const only = node.specifiers[0] as any;\r\n if (only?.local?.name) {\r\n defaultExportLocalName = only.local.name;\r\n returnDefaultProperty = true;\r\n node.specifiers = [];\r\n }\r\n }\r\n }\r\n\r\n path.remove();\r\n },\r\n\r\n Program: {\r\n exit(path: NodePath<t.Program>) {\r\n const program = path.node;\r\n\r\n if (!defaultExportLocalName) {\r\n throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);\r\n }\r\n\r\n const depsIdent = t.identifier(opts.depsParam ?? DEFAULTS.depsParam);\r\n const runtimeKey = opts.runtimeKey ?? DEFAULTS.runtimeKey;\r\n\r\n // const __imports = (deps has runtimeKey) ? deps[runtimeKey] : (deps || {});\r\n const importsIdent = t.identifier(\"__imports\");\r\n const importsInit = makeImportMapExpr(depsIdent, runtimeKey);\r\n const importsDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(importsIdent, importsInit),\r\n ]);\r\n\r\n // helper:\r\n // const __default = (m) => (m && typeof m === \"object\" && \"default\" in m ? m.default : m);\r\n const defaultHelperIdent = t.identifier(\"__default\");\r\n const defaultHelperDecl = t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n defaultHelperIdent,\r\n t.arrowFunctionExpression(\r\n [t.identifier(\"m\")],\r\n t.conditionalExpression(\r\n t.logicalExpression(\r\n \"&&\",\r\n t.logicalExpression(\r\n \"&&\",\r\n t.identifier(\"m\"),\r\n t.binaryExpression(\r\n \"===\",\r\n t.unaryExpression(\"typeof\", t.identifier(\"m\")),\r\n t.stringLiteral(\"object\")\r\n )\r\n ),\r\n t.binaryExpression(\"in\", t.stringLiteral(\"default\"), t.identifier(\"m\"))\r\n ),\r\n t.memberExpression(t.identifier(\"m\"), t.identifier(\"default\")),\r\n t.identifier(\"m\")\r\n )\r\n )\r\n ),\r\n ]);\r\n\r\n // Build injected module locals inside wrapper\r\n const injectedStmts: t.Statement[] = [importsDecl, defaultHelperDecl];\r\n\r\n for (const [importId, specs] of injectedImportsById.entries()) {\r\n const modIdent = t.identifier(\r\n `__m_${importId.replace(/[^a-zA-Z0-9_$]/g, \"_\")}`\r\n );\r\n\r\n // const __m_xxx = __imports[\"<importId>\"];\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n modIdent,\r\n t.memberExpression(importsIdent, t.stringLiteral(importId), true)\r\n ),\r\n ])\r\n );\r\n\r\n const named: Array<{ imported: string; local: string }> = [];\r\n\r\n for (const s of specs) {\r\n if (s.kind === \"default\") {\r\n // const Local = __default(__m_xxx);\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.identifier(s.local),\r\n t.callExpression(defaultHelperIdent, [modIdent])\r\n ),\r\n ])\r\n );\r\n } else if (s.kind === \"namespace\") {\r\n // const Local = __m_xxx;\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(t.identifier(s.local), modIdent),\r\n ])\r\n );\r\n } else {\r\n named.push({imported: s.imported, local: s.local});\r\n }\r\n }\r\n\r\n if (named.length) {\r\n // const { A, B: C } = (__m_xxx ?? {});\r\n injectedStmts.push(\r\n t.variableDeclaration(\"const\", [\r\n t.variableDeclarator(\r\n t.objectPattern(\r\n named.map(({imported, local}) =>\r\n t.objectProperty(\r\n t.identifier(imported),\r\n t.identifier(local),\r\n false,\r\n imported === local\r\n )\r\n )\r\n ),\r\n t.logicalExpression(\"||\", modIdent, t.objectExpression([]))\r\n ),\r\n ])\r\n );\r\n }\r\n }\r\n\r\n const returnExpr = returnDefaultProperty\r\n ? t.memberExpression(\r\n t.identifier(defaultExportLocalName),\r\n t.identifier(\"default\")\r\n )\r\n : t.identifier(defaultExportLocalName);\r\n\r\n // Wrapper body:\r\n // injectedStmts...\r\n // <original body>\r\n // return <defaultExport>\r\n const wrapperBody: t.Statement[] = [];\r\n wrapperBody.push(...injectedStmts);\r\n wrapperBody.push(...program.body);\r\n wrapperBody.push(t.returnStatement(returnExpr));\r\n\r\n const wrapper = t.exportDefaultDeclaration(\r\n t.functionDeclaration(\r\n null,\r\n [depsIdent],\r\n t.blockStatement(wrapperBody)\r\n )\r\n );\r\n\r\n // Final program:\r\n // kept imports at module scope\r\n // export default function(deps) { ... }\r\n // kept named exports (same as your old behavior)\r\n program.body = [...keptImports, wrapper, ...keptNamedExports] as any;\r\n },\r\n },\r\n },\r\n };\r\n}","// src/utils/generate-plugin-inputs.ts\r\nimport path from \"node:path\";\r\nimport * as fs from \"node:fs\";\r\n\r\nconst EXT_PATTERN = /\\.(tsx?|jsx?)$/i;\r\n\r\nexport type PluginInputs = Record<string, string>;\r\n\r\nexport type GeneratePluginInputsOptions = {\r\n /**\r\n * If true, also generates `app.tsx` that imports every discovered entry\r\n * (handy for dev/HMR).\r\n *\r\n * Default: true\r\n */\r\n writeAppEntry?: boolean;\r\n\r\n /**\r\n * Name of the generated app entry file (inside srcRoot).\r\n *\r\n * Default: \"app.tsx\"\r\n */\r\n appEntryName?: string;\r\n\r\n /**\r\n * Adds the generated app entry to the returned Rollup inputs map.\r\n *\r\n * Default: true\r\n */\r\n includeAppEntryInInputs?: boolean;\r\n\r\n /**\r\n * Key name used for the generated app entry in Rollup inputs.\r\n *\r\n * Default: \"__app_entry\"\r\n */\r\n appEntryKey?: string;\r\n\r\n /**\r\n * Extra directory names to ignore (case-insensitive).\r\n */\r\n ignoreDirs?: string[];\r\n\r\n /**\r\n * Extra “component-like” directory names to ignore (case-insensitive, exact match).\r\n */\r\n componentLikeDirs?: string[];\r\n\r\n /**\r\n * Whether to print discovered inputs to console.\r\n *\r\n * Default: true\r\n */\r\n verbose?: boolean;\r\n};\r\n\r\n// folders you typically never want as rollup inputs\r\nconst DEFAULT_IGNORE_DIRS = new Set<string>([\r\n \"node_modules\",\r\n \".git\",\r\n \".vite\",\r\n \".internal\",\r\n \"dist\",\r\n \"build\",\r\n \"public\",\r\n]);\r\n\r\n// “component-like” folders that should NOT produce entrypoints\r\n// Strict: exact folder-name matches only (case-insensitive)\r\nconst DEFAULT_COMPONENT_LIKE_DIRS = new Set<string>([\r\n \"component\",\r\n \"components\",\r\n \"ui\",\r\n \"uis\",\r\n \"widget\",\r\n \"widgets\",\r\n \"atom\",\r\n \"atoms\",\r\n \"molecule\",\r\n \"molecules\",\r\n \"organism\",\r\n \"organisms\",\r\n \"layout\",\r\n \"layouts\",\r\n \"partial\",\r\n \"partials\",\r\n]);\r\n\r\nfunction normalizeName(x: unknown): string {\r\n return String(x ?? \"\").toLowerCase();\r\n}\r\n\r\nfunction makeIgnoreSets(opts?: GeneratePluginInputsOptions): {\r\n ignoreDirs: Set<string>;\r\n componentLikeDirs: Set<string>;\r\n} {\r\n const ignoreDirs = new Set(DEFAULT_IGNORE_DIRS);\r\n const componentLikeDirs = new Set(DEFAULT_COMPONENT_LIKE_DIRS);\r\n\r\n for (const d of opts?.ignoreDirs ?? []) ignoreDirs.add(normalizeName(d));\r\n for (const d of opts?.componentLikeDirs ?? []) componentLikeDirs.add(normalizeName(d));\r\n\r\n return { ignoreDirs, componentLikeDirs };\r\n}\r\n\r\nfunction isIgnoredDir(\r\n dirName: string,\r\n sets: { ignoreDirs: Set<string>; componentLikeDirs: Set<string> }\r\n): boolean {\r\n const name = normalizeName(dirName);\r\n return sets.ignoreDirs.has(name) || sets.componentLikeDirs.has(name);\r\n}\r\n\r\n/**\r\n * Creates an app.tsx file that simply imports every discovered entry.\r\n * Helpful for HMR / dev mode.\r\n */\r\nfunction writeAppEntryFile(inputs: PluginInputs, srcRoot: string, appEntryName: string): void {\r\n const app = path.join(srcRoot, appEntryName);\r\n const lines: string[] = [\"// Auto-generated – do not edit\", \"\"];\r\n\r\n const entries = Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b));\r\n\r\n for (const [name, full] of entries) {\r\n const rel =\r\n \"./\" + path.relative(srcRoot, full).replace(/\\\\/g, \"/\").replace(EXT_PATTERN, \"\");\r\n\r\n const variable = name.replace(/[^a-zA-Z0-9_$]/g, \"_\").replace(/^(\\d)/, \"_$1\");\r\n\r\n lines.push(`import * as ${variable} from '${rel}';`);\r\n lines.push(`console.log('${name} loaded:', ${variable});`, \"\");\r\n }\r\n\r\n fs.writeFileSync(app, lines.join(\"\\n\"), \"utf8\");\r\n // eslint-disable-next-line no-console\r\n console.log(`✅ Generated ${appEntryName} in ${srcRoot}`);\r\n}\r\n\r\n/**\r\n * Convert a relative path like \"foo/bar/index.tsx\" to a dot key.\r\n * If `collapseIndex` is true, \"foo/bar/index\" becomes \"foo.bar\".\r\n * Otherwise it becomes \"foo.bar.index\".\r\n */\r\nfunction pathToKey(relNoExt: string, opts: { collapseIndex: boolean }): string {\r\n let normalized = relNoExt.replace(/\\\\/g, \"/\");\r\n\r\n if (opts.collapseIndex) {\r\n normalized = normalized.replace(/\\/index$/i, \"\");\r\n }\r\n\r\n let key = normalized.split(\"/\").filter(Boolean).join(\".\");\r\n if (!key) key = \"index\";\r\n return key;\r\n}\r\n\r\n/**\r\n * Recursively collect entry files under dirPath.\r\n *\r\n * Rule:\r\n * - Prefer collapsing \".../index.tsx\" => \"...\" for nicer keys\r\n * - BUT if that key would collide with another entry, fallback to explicit \"...index\"\r\n * (e.g. \"foo.index\") for the index file ONLY.\r\n */\r\nfunction crawl(\r\n dirPath: string,\r\n baseDir: string,\r\n acc: PluginInputs,\r\n sets: { ignoreDirs: Set<string>; componentLikeDirs: Set<string> },\r\n appEntryAbsPath: string\r\n): void {\r\n if (!fs.existsSync(dirPath)) return;\r\n\r\n for (const item of fs.readdirSync(dirPath)) {\r\n const full = path.join(dirPath, item);\r\n const stat = fs.statSync(full);\r\n\r\n if (stat.isDirectory()) {\r\n if (isIgnoredDir(item, sets)) continue;\r\n crawl(full, baseDir, acc, sets, appEntryAbsPath);\r\n continue;\r\n }\r\n\r\n if (!EXT_PATTERN.test(item)) continue;\r\n\r\n // Don't include the generated entry itself (prevents self-import)\r\n if (path.resolve(full) === path.resolve(appEntryAbsPath)) {\r\n continue;\r\n }\r\n\r\n const relNoExt = path.relative(baseDir, full).replace(EXT_PATTERN, \"\");\r\n const isIndexFile = /(^|[\\\\/])index$/i.test(relNoExt);\r\n\r\n // Preferred key: collapse \".../index\" => \"...\"\r\n const preferred = pathToKey(relNoExt, { collapseIndex: true });\r\n\r\n // Explicit key: keep \".../index\" => \"...index\"\r\n // Example: \"foo/index\" => \"foo.index\"\r\n const explicit = pathToKey(relNoExt, { collapseIndex: false });\r\n\r\n let name = preferred;\r\n\r\n // If preferred collides, ONLY the index file switches to explicit path key.\r\n const existing = acc[name];\r\n if (existing && path.resolve(existing) !== path.resolve(full)) {\r\n if (isIndexFile) {\r\n // Use foo.index (or deeper.path.index) instead of suffixing __2\r\n if (!acc[explicit]) {\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n `⚠️ Key collision for \"${preferred}\" — using \"${explicit}\" for index file`,\r\n { existing: acc[preferred], incoming: full }\r\n );\r\n name = explicit;\r\n } else {\r\n // Extremely rare: even explicit collides (e.g. duplicate paths via symlinks)\r\n let i = 2;\r\n let next = `${explicit}__${i}`;\r\n while (acc[next]) {\r\n i += 1;\r\n next = `${explicit}__${i}`;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn(`⚠️ Key collision for \"${explicit}\" — using \"${next}\"`, {\r\n existing: acc[explicit],\r\n incoming: full,\r\n });\r\n name = next;\r\n }\r\n } else {\r\n // Non-index collision: suffix like original behavior\r\n let i = 2;\r\n let next = `${name}__${i}`;\r\n while (acc[next]) {\r\n i += 1;\r\n next = `${name}__${i}`;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn(`⚠️ Input key collision \"${name}\" -> using \"${next}\"`, {\r\n existing: acc[name],\r\n incoming: full,\r\n });\r\n name = next;\r\n }\r\n }\r\n\r\n acc[name] = full;\r\n }\r\n}\r\n\r\n/**\r\n * Discover integration pages/components and return a Rollup input map.\r\n *\r\n * @param srcRoot absolute or relative path to the source folder (e.g. \"resources/embed/ts\")\r\n * @param options\r\n * @returns Rollup input map: { [key]: absolutePath }\r\n */\r\nexport function generatePluginInputs(\r\n srcRoot: string = path.resolve(process.cwd(), \"ts\"),\r\n options: GeneratePluginInputsOptions = {}\r\n): PluginInputs {\r\n const {\r\n writeAppEntry = true,\r\n appEntryName = \"app.tsx\",\r\n includeAppEntryInInputs = true,\r\n appEntryKey = \"__app_entry\",\r\n verbose = true,\r\n } = options;\r\n\r\n const absRoot = path.resolve(srcRoot);\r\n const inputs: PluginInputs = {};\r\n\r\n const sets = makeIgnoreSets(options);\r\n const appEntryAbsPath = path.join(absRoot, appEntryName);\r\n\r\n // Crawl everything under absRoot (no folder assumptions)\r\n crawl(absRoot, absRoot, inputs, sets, appEntryAbsPath);\r\n\r\n if (verbose) {\r\n // eslint-disable-next-line no-console\r\n console.log(\"✅ Integrations discovered:\", inputs);\r\n }\r\n\r\n if (writeAppEntry) {\r\n writeAppEntryFile(inputs, absRoot, appEntryName);\r\n }\r\n\r\n if (!includeAppEntryInInputs) return inputs;\r\n\r\n return { ...inputs, [appEntryKey]: appEntryAbsPath };\r\n}"],"mappings":"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","names":["path","shouldInject"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fortiplugin-bundle-adapter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"build": "tsup",
|
|
21
21
|
"dev": "tsup --watch",
|
|
22
22
|
"typecheck": "tsc -p tsconfig.json",
|
|
23
|
-
"test:transform": "node tests/run-transform.mjs"
|
|
23
|
+
"test:transform": "node tests/run-transform.mjs",
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
25
|
+
"postPublish": "npm version patch && git push origin --follow-tags"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
28
|
"@babel/core": "^7.28.5",
|