fortiplugin-bundle-adapter 0.0.2 → 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 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(path) {
96
- const node = path.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
- path.remove();
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
- path.remove();
117
+ path2.remove();
117
118
  },
118
- ExportDefaultDeclaration(path) {
119
- const decl = path.node.declaration;
119
+ ExportDefaultDeclaration(path2) {
120
+ const decl = path2.node.declaration;
120
121
  if (t.isIdentifier(decl)) {
121
122
  defaultExportLocalName = decl.name;
122
- path.remove();
123
+ path2.remove();
123
124
  return;
124
125
  }
125
- const id = path.scope.generateUidIdentifier("defaultExport");
126
- path.replaceWith(
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(path) {
132
- const node = path.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
- path.remove();
156
+ path2.remove();
156
157
  },
157
158
  Program: {
158
- exit(path) {
159
- const program = path.node;
159
+ exit(path2) {
160
+ const program = path2.node;
160
161
  if (!defaultExportLocalName) {
161
- throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);
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
@@ -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
- export { type FortiPrepOptions, type FortiPrepTransformOptions, prep as default, fortiPrepTransform };
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
- export { type FortiPrepOptions, type FortiPrepTransformOptions, prep as default, fortiPrepTransform };
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(path) {
59
- const node = path.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
- path.remove();
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
- path.remove();
79
+ path2.remove();
80
80
  },
81
- ExportDefaultDeclaration(path) {
82
- const decl = path.node.declaration;
81
+ ExportDefaultDeclaration(path2) {
82
+ const decl = path2.node.declaration;
83
83
  if (t.isIdentifier(decl)) {
84
84
  defaultExportLocalName = decl.name;
85
- path.remove();
85
+ path2.remove();
86
86
  return;
87
87
  }
88
- const id = path.scope.generateUidIdentifier("defaultExport");
89
- path.replaceWith(
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(path) {
95
- const node = path.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
- path.remove();
118
+ path2.remove();
119
119
  },
120
120
  Program: {
121
- exit(path) {
122
- const program = path.node;
121
+ exit(path2) {
122
+ const program = path2.node;
123
123
  if (!defaultExportLocalName) {
124
- throw path.buildCodeFrameError(DEFAULT_EXPORT_ERROR);
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
@@ -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.2",
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",