@forinda/kickjs-cli 5.0.2 → 5.2.0

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v5.0.2
2
+ * @forinda/kickjs-cli v5.2.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,10 +8,12 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { dirname, extname, join, relative, resolve, sep } from "node:path";
12
- import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
11
+ import { t as __exportAll } from "./rolldown-runtime-CYBbkZNy.mjs";
12
+ import { dirname, join, relative, resolve, sep } from "node:path";
13
13
  import { statSync } from "node:fs";
14
+ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
14
15
  import { globSync } from "glob";
16
+ import { groupAssetKeys } from "@forinda/kickjs";
15
17
  //#region src/typegen/scanner.ts
16
18
  /** Decorators that mark a class as DI-managed */
17
19
  const DECORATOR_NAMES = [
@@ -729,12 +731,12 @@ function discoverAssets(assetMap, cwd) {
729
731
  posix: true
730
732
  });
731
733
  matches.sort();
732
- for (const rel of matches) {
733
- const key = stripExt(rel);
734
- const logical = `${namespace}/${key}`;
734
+ const { pairs } = groupAssetKeys(namespace, matches, { strategy: entry.keys ?? "auto" });
735
+ for (const { key: logical } of pairs) {
736
+ const subKey = logical.slice(namespace.length + 1);
735
737
  seen.set(logical, {
736
738
  namespace,
737
- key
739
+ key: subKey
738
740
  });
739
741
  }
740
742
  }
@@ -798,7 +800,7 @@ export {}
798
800
  }
799
801
  const LEAF = Symbol("asset-leaf");
800
802
  function renderTree(node, indent) {
801
- const keys = Object.keys(node).sort();
803
+ const keys = Object.keys(node).toSorted();
802
804
  const lines = [];
803
805
  for (const key of keys) {
804
806
  const child = node[key];
@@ -822,10 +824,6 @@ function isDir(path) {
822
824
  return false;
823
825
  }
824
826
  }
825
- function stripExt(path) {
826
- const ext = extname(path);
827
- return ext ? path.slice(0, -ext.length) : path;
828
- }
829
827
  //#endregion
830
828
  //#region src/typegen/generator.ts
831
829
  /**
@@ -953,7 +951,7 @@ export type ${typeName} = never
953
951
  `;
954
952
  return `${HEADER}
955
953
  export type ${typeName} =
956
- ${[...new Set(names)].sort().map((n) => ` | '${n}'`).join("\n")}
954
+ ${[...new Set(names)].toSorted().map((n) => ` | '${n}'`).join("\n")}
957
955
  `;
958
956
  }
959
957
  /** Render the barrel index that re-exports the union types */
@@ -969,203 +967,11 @@ export type { ModuleToken } from './modules'
969
967
  // \`dependsOn: ['TenantAdapter']\`, \`assets.mails.welcome()\`, and
970
968
  // \`@Value('PORT')\` to resolve.
971
969
  import './registry'
972
- import './routes'
970
+ import './kick__routes'
973
971
  import './plugins'
974
972
  import './augmentations'
975
973
  import './assets'
976
- ${includeEnv ? "import './env'\n" : ""}`;
977
- }
978
- /**
979
- * Render the `query` field's TypeScript type for a single route.
980
- *
981
- * - When `@ApiQueryParams` is absent (`queryFilterable === null`), emits
982
- * `unknown` so the user gets nothing extra.
983
- * - When the decorator is present, emits an object literal whose keys
984
- * are the standard query string keys (`filter`, `sort`, `q`, `page`,
985
- * `limit`). `sort` is narrowed to a string-literal union of allowed
986
- * field names with optional `-` direction prefix.
987
- */
988
- function renderQueryShape(m) {
989
- if (m.queryFilterable === null) return "unknown";
990
- const sortable = m.querySortable ?? [];
991
- return `{ filter?: string | string[]; sort?: ${sortable.length > 0 ? sortable.flatMap((f) => [`'${f}'`, `'-${f}'`]).join(" | ") : "string"}; q?: string; page?: string; limit?: string }`;
992
- }
993
- /** Render JSDoc lines summarising the @ApiQueryParams whitelist */
994
- function renderQueryDocLines(m) {
995
- const lines = [];
996
- if (m.queryFilterable && m.queryFilterable.length > 0) lines.push(`Filterable: ${m.queryFilterable.join(", ")}`);
997
- if (m.querySortable && m.querySortable.length > 0) lines.push(`Sortable: ${m.querySortable.join(", ")}`);
998
- if (m.querySearchable && m.querySearchable.length > 0) lines.push(`Searchable: ${m.querySearchable.join(", ")}`);
999
- return lines;
1000
- }
1001
- /**
1002
- * Plan a schema import for hoisting at the top of `routes.ts`. Returns
1003
- * the alias the in-namespace code should use, or `null` if the schema
1004
- * cannot be referenced (no validator configured, or source unresolvable).
1005
- *
1006
- * Aliases are unique per (alias-counter) so two schemas named
1007
- * `createTaskSchema` from different modules don't collide.
1008
- */
1009
- function planSchemaImport(schema, routeFilePath, routesOutFile, schemaValidator, imports) {
1010
- if (!schema || schemaValidator !== "zod") return null;
1011
- if (schema.source === null) return null;
1012
- const specifier = resolveSchemaImportSpecifier(schema.source, routeFilePath, routesOutFile);
1013
- if (specifier === "unknown") return null;
1014
- const key = `${specifier}::${schema.identifier}`;
1015
- let alias = imports.get(key)?.specifier;
1016
- if (!alias) {
1017
- alias = `_S${imports.size}`;
1018
- imports.set(key, {
1019
- identifier: schema.identifier,
1020
- specifier: alias
1021
- });
1022
- } else alias = imports.get(key).specifier;
1023
- return alias;
1024
- }
1025
- /** Build the `import type { ... } from '...'` lines for hoisted schema imports */
1026
- function renderSchemaImports(imports) {
1027
- if (imports.size === 0) return "";
1028
- const lines = [];
1029
- for (const [key, value] of imports) {
1030
- const [path] = key.split("::");
1031
- lines.push(`import type { ${value.identifier} as ${value.specifier} } from '${path}'`);
1032
- }
1033
- return lines.join("\n") + "\n";
1034
- }
1035
- /**
1036
- * Compute the import specifier the generated `routes.d.ts` should use to
1037
- * reach a schema declared either in the controller file (empty string)
1038
- * or imported from elsewhere (relative path or bare module name).
1039
- *
1040
- * - Bare module names (`zod`, `@scope/pkg`) are returned as-is.
1041
- * - Relative paths (`./users.dto`, `../shared/schema`) are resolved
1042
- * against the controller's file path, then re-relativised against the
1043
- * directory containing `routes.d.ts`.
1044
- * - Empty string (same-file schema) becomes a relative path from the
1045
- * `routes.d.ts` directory back to the controller file.
1046
- */
1047
- function resolveSchemaImportSpecifier(source, routeFilePath, routesOutFile) {
1048
- if (source === null) return "unknown";
1049
- const routesDir = dirname(routesOutFile);
1050
- if (source === "") {
1051
- let rel = relative(routesDir, routeFilePath).split(sep).join("/");
1052
- rel = rel.replace(/\.(ts|tsx|mts|cts)$/i, "");
1053
- if (!rel.startsWith(".")) rel = "./" + rel;
1054
- return rel;
1055
- }
1056
- if (!source.startsWith(".") && !source.startsWith("/")) return source;
1057
- let rel = relative(routesDir, resolve(dirname(routeFilePath), source)).split(sep).join("/");
1058
- rel = rel.replace(/\.(ts|tsx|mts|cts)$/i, "");
1059
- if (!rel.startsWith(".")) rel = "./" + rel;
1060
- return rel;
1061
- }
1062
- /**
1063
- * Render the `KickEnv` + `NodeJS.ProcessEnv` augmentation file from a
1064
- * detected env schema. Mirrors the routes.ts pattern: emits as a `.ts`
1065
- * file (not `.d.ts`) so the top-level `import type schema from '...'`
1066
- * actually resolves under `moduleResolution: 'bundler'`.
1067
- *
1068
- * Returns `null` when no env file was discovered, so the caller can
1069
- * skip writing the file altogether (rather than emitting an empty
1070
- * augmentation that would shadow `KickEnv` to a useless `{}`).
1071
- */
1072
- function renderEnv(env, envOutFile) {
1073
- if (!env) return null;
1074
- let rel = relative(dirname(envOutFile), env.filePath).split(sep).join("/");
1075
- rel = rel.replace(/\.(ts|tsx|mts|cts)$/i, "");
1076
- if (!rel.startsWith(".")) rel = "./" + rel;
1077
- return `${HEADER}
1078
- // Importing the schema as a type lets us infer its shape without
1079
- // pulling in any runtime code. \`Awaited<>\` strips an accidental
1080
- // Promise wrap on dynamic-imported defaults.
1081
- import type _envSchema from '${rel}'
1082
-
1083
- // Local type alias — interfaces can only \`extend\` an identifier,
1084
- // not an inline import expression, so we resolve the schema's
1085
- // inferred shape into a named type first.
1086
- type _KickEnvShape = import('zod').infer<typeof _envSchema>
1087
-
1088
- declare global {
1089
- /**
1090
- * Typed environment registry. Augmented from \`${env.relativePath}\`
1091
- * so \`@Value('PORT')\`, \`Env<'PORT'>\`, and \`process.env.PORT\` are
1092
- * all type-safe and autocomplete.
1093
- */
1094
- interface KickEnv extends _KickEnvShape {}
1095
-
1096
- // eslint-disable-next-line @typescript-eslint/no-namespace
1097
- namespace NodeJS {
1098
- /**
1099
- * Narrow \`process.env\` so known keys exist as \`string\` (the raw
1100
- * pre-Zod-coercion form). \`@Value\` and the \`ConfigService\` apply
1101
- * the schema's transforms internally; access \`process.env\` directly
1102
- * only when you need the raw string. Unknown keys still resolve to
1103
- * \`string | undefined\` via the base @types/node declaration.
1104
- */
1105
- interface ProcessEnv extends Record<keyof KickEnv, string> {}
1106
- }
1107
- }
1108
-
1109
- export {}
1110
- `;
1111
- }
1112
- /**
1113
- * Render the `KickRoutes` global namespace augmentation. Each interface
1114
- * inside corresponds to a controller class; each property is a single
1115
- * route method on that controller, conforming to `RouteShape`.
1116
- *
1117
- * Fills `params` from URL patterns, `query` from `@ApiQueryParams`, and
1118
- * `body`/`query`/`params` (when schema-validated) from the configured
1119
- * schema validator. `response` is emitted as `unknown`.
1120
- */
1121
- function renderRoutes(routes, routesOutFile, schemaValidator) {
1122
- if (routes.length === 0) return `${HEADER}
1123
- // (no routes discovered yet — annotate a controller method with
1124
- // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
1125
- declare global {
1126
- // eslint-disable-next-line @typescript-eslint/no-namespace
1127
- namespace KickRoutes {}
1128
- }
1129
-
1130
- export {}
1131
- `;
1132
- const byController = /* @__PURE__ */ new Map();
1133
- for (const r of routes) {
1134
- const arr = byController.get(r.controller) ?? [];
1135
- arr.push(r);
1136
- byController.set(r.controller, arr);
1137
- }
1138
- const schemaImports = /* @__PURE__ */ new Map();
1139
- const renderField = (schema, routeFilePath) => {
1140
- const alias = planSchemaImport(schema, routeFilePath, routesOutFile, schemaValidator, schemaImports);
1141
- return alias ? `import('zod').infer<typeof ${alias}>` : null;
1142
- };
1143
- const interfaces = [];
1144
- for (const [controller, methods] of byController) {
1145
- const lines = [` interface ${controller} {`];
1146
- for (const m of methods) {
1147
- const urlParamsType = m.pathParams.length > 0 ? `{ ${m.pathParams.map((p) => `${p}: string`).join("; ")} }` : "{}";
1148
- const bodySchemaType = renderField(m.bodySchema, m.filePath);
1149
- const querySchemaType = renderField(m.querySchema, m.filePath);
1150
- const paramsType = renderField(m.paramsSchema, m.filePath) ?? urlParamsType;
1151
- const bodyType = bodySchemaType ?? "unknown";
1152
- const queryType = querySchemaType ?? renderQueryShape(m);
1153
- const docLines = renderQueryDocLines(m);
1154
- lines.push(` /**`, ` * ${m.httpMethod} ${m.path}`, ...docLines.map((d) => ` * ${d}`), ` */`, ` ${m.method}: {`, ` params: ${paramsType}`, ` body: ${bodyType}`, ` query: ${queryType}`, ` response: unknown`, ` }`);
1155
- }
1156
- lines.push(" }");
1157
- interfaces.push(lines.join("\n"));
1158
- }
1159
- return `${HEADER}${renderSchemaImports(schemaImports)}
1160
- declare global {
1161
- // eslint-disable-next-line @typescript-eslint/no-namespace
1162
- namespace KickRoutes {
1163
- ${interfaces.join("\n")}
1164
- }
1165
- }
1166
-
1167
- export {}
1168
- `;
974
+ ${includeEnv ? "import './kick__env'\n" : ""}`;
1169
975
  }
1170
976
  /**
1171
977
  * Render the `KickJsPluginRegistry` augmentation. Each entry maps the
@@ -1182,7 +988,7 @@ export {}
1182
988
  function renderPlugins(items) {
1183
989
  const byName = /* @__PURE__ */ new Map();
1184
990
  for (const item of items) if (!byName.has(item.name)) byName.set(item.name, item);
1185
- const entries = [...byName.values()].sort((a, b) => a.name.localeCompare(b.name)).map((item) => ` '${item.name}': '${item.kind}'`).join("\n");
991
+ const entries = [...byName.values()].toSorted((a, b) => a.name.localeCompare(b.name)).map((item) => ` '${item.name}': '${item.kind}'`).join("\n");
1186
992
  return `${HEADER}
1187
993
  declare module '@forinda/kickjs' {
1188
994
  /**
@@ -1225,7 +1031,7 @@ export {}
1225
1031
  const byName = /* @__PURE__ */ new Map();
1226
1032
  for (const item of items) if (!byName.has(item.name)) byName.set(item.name, item);
1227
1033
  const blocks = [];
1228
- for (const item of [...byName.values()].sort((a, b) => a.name.localeCompare(b.name))) {
1034
+ for (const item of [...byName.values()].toSorted((a, b) => a.name.localeCompare(b.name))) {
1229
1035
  const docLines = [];
1230
1036
  if (item.description) for (const line of item.description.split("\n")) docLines.push(` * ${line}`);
1231
1037
  if (item.example) {
@@ -1254,14 +1060,12 @@ async function generateTypes(opts) {
1254
1060
  const { classes, routes = [], tokens = [], injects = [], collisions = [], env = null, pluginsAndAdapters = [], augmentations = [], assets = {
1255
1061
  entries: [],
1256
1062
  count: 0
1257
- }, outDir, allowDuplicates = false, schemaValidator = false } = opts;
1063
+ }, outDir, allowDuplicates = false, schemaValidator: _schemaValidator = false } = opts;
1258
1064
  if (collisions.length > 0 && !allowDuplicates) throw new TokenCollisionError(collisions);
1259
1065
  await mkdir(outDir, { recursive: true });
1260
1066
  const registryFile = join(outDir, "registry.d.ts");
1261
1067
  const servicesFile = join(outDir, "services.d.ts");
1262
1068
  const modulesFile = join(outDir, "modules.d.ts");
1263
- const routesFile = join(outDir, "routes.ts");
1264
- const envFile = join(outDir, "env.ts");
1265
1069
  const pluginsFile = join(outDir, "plugins.d.ts");
1266
1070
  const augmentationsFile = join(outDir, "augmentations.d.ts");
1267
1071
  const assetsFile = join(outDir, "assets.d.ts");
@@ -1279,16 +1083,13 @@ async function generateTypes(opts) {
1279
1083
  const modules = classes.filter((c) => c.decorator === "Module").map((c) => c.className);
1280
1084
  const servicesContent = renderUnion("ServiceToken", allServices, "(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)");
1281
1085
  const modulesContent = renderUnion("ModuleToken", modules, "(no @Module classes discovered — `kick g module <name>` to add one)");
1282
- const routesContent = renderRoutes(routes, routesFile, schemaValidator);
1283
- const envContent = renderEnv(env, envFile);
1284
1086
  const pluginsContent = renderPlugins(pluginsAndAdapters);
1285
1087
  const augmentationsContent = renderAugmentations(augmentations);
1286
1088
  const assetsContent = renderAssetTypes(assets);
1287
- const indexContent = renderIndex(envContent !== null);
1089
+ const indexContent = renderIndex(env !== null);
1288
1090
  await writeFile(registryFile, registryContent, "utf-8");
1289
1091
  await writeFile(servicesFile, servicesContent, "utf-8");
1290
1092
  await writeFile(modulesFile, modulesContent, "utf-8");
1291
- await writeFile(routesFile, routesContent, "utf-8");
1292
1093
  await writeFile(pluginsFile, pluginsContent, "utf-8");
1293
1094
  await writeFile(augmentationsFile, augmentationsContent, "utf-8");
1294
1095
  await writeFile(assetsFile, assetsContent, "utf-8");
@@ -1297,16 +1098,11 @@ async function generateTypes(opts) {
1297
1098
  registryFile,
1298
1099
  servicesFile,
1299
1100
  modulesFile,
1300
- routesFile,
1301
1101
  pluginsFile,
1302
1102
  augmentationsFile,
1303
1103
  assetsFile,
1304
1104
  indexFile
1305
1105
  ];
1306
- if (envContent) {
1307
- await writeFile(envFile, envContent, "utf-8");
1308
- written.push(envFile);
1309
- }
1310
1106
  await writeFile(join(dirname(outDir), ".gitignore"), "# Auto-generated by kick typegen\n*\n", "utf-8");
1311
1107
  const uniquePluginNames = new Set(pluginsAndAdapters.map((p) => p.name)).size;
1312
1108
  const uniqueAugmentations = new Set(augmentations.map((a) => a.name)).size;
@@ -1318,7 +1114,7 @@ async function generateTypes(opts) {
1318
1114
  pluginEntries: uniquePluginNames,
1319
1115
  augmentationEntries: uniqueAugmentations,
1320
1116
  assetEntries: assets.count,
1321
- envWritten: envContent !== null,
1117
+ envWritten: env !== null,
1322
1118
  written,
1323
1119
  resolvedCollisions: collisions.length
1324
1120
  };
@@ -1374,6 +1170,10 @@ function suggestRename(name) {
1374
1170
  *
1375
1171
  * @module @forinda/kickjs-cli/typegen
1376
1172
  */
1173
+ var typegen_exports = /* @__PURE__ */ __exportAll({
1174
+ runTypegen: () => runTypegen,
1175
+ watchTypegen: () => watchTypegen
1176
+ });
1377
1177
  /** Resolve options to absolute paths */
1378
1178
  function resolveOptions(opts) {
1379
1179
  const cwd = opts.cwd ?? process.cwd();
@@ -1419,6 +1219,20 @@ async function runTypegen(opts = {}) {
1419
1219
  allowDuplicates,
1420
1220
  schemaValidator
1421
1221
  });
1222
+ if (opts.runPlugins !== false) try {
1223
+ const { runAllPluginTypegens } = await import("./run-plugins-B1R0HG0g.mjs");
1224
+ const { loadKickConfig } = await import("./config-DDrgs-I3.mjs").then((n) => n.n);
1225
+ await runAllPluginTypegens({
1226
+ cwd,
1227
+ config: await loadKickConfig(cwd),
1228
+ silent: true
1229
+ });
1230
+ } catch (err) {
1231
+ if (!silent) {
1232
+ const msg = err instanceof Error ? err.message : String(err);
1233
+ console.warn(` kick typegen: plugin pipeline failed (${msg}) — continuing`);
1234
+ }
1235
+ }
1422
1236
  const tokenWarnings = validateTokenConventions(scan.tokens);
1423
1237
  const elapsed = Date.now() - start;
1424
1238
  if (!silent) {
@@ -1444,7 +1258,96 @@ async function runTypegen(opts = {}) {
1444
1258
  tokenWarnings
1445
1259
  };
1446
1260
  }
1261
+ /**
1262
+ * Watch mode for `kick typegen --watch`.
1263
+ *
1264
+ * Uses Node's built-in `fs.watch` (recursive, available on Linux 22+ and
1265
+ * macOS 19+). Falls back gracefully if recursive watch is not supported.
1266
+ *
1267
+ * Debounces re-runs by 100ms so a bulk file change (e.g. `kick g module`
1268
+ * creating 5 files at once) emits one regen, not five.
1269
+ *
1270
+ * In watch mode collisions are reported but never thrown — the watcher
1271
+ * keeps running so the user can fix the rename and the next scan
1272
+ * recovers automatically.
1273
+ *
1274
+ * Returns a `stop()` function that closes the watcher.
1275
+ */
1276
+ async function watchTypegen(opts = {}) {
1277
+ const resolved = resolveOptions(opts);
1278
+ const { srcDir, silent, cwd } = resolved;
1279
+ const runOpts = {
1280
+ ...resolved,
1281
+ allowDuplicates: true,
1282
+ runPlugins: false
1283
+ };
1284
+ const forcePolling = process.env.KICKJS_WATCH_POLLING === "1" || process.env.KICKJS_WATCH_POLLING === "true";
1285
+ const [{ runAllPluginTypegens }, { loadKickConfig }] = await Promise.all([import("./run-plugins-B1R0HG0g.mjs"), import("./config-DDrgs-I3.mjs").then((n) => n.n)]);
1286
+ const pluginConfig = await loadKickConfig(cwd);
1287
+ const runPlugins = () => runAllPluginTypegens({
1288
+ cwd,
1289
+ config: pluginConfig,
1290
+ silent: true
1291
+ }).catch(() => {});
1292
+ await safeRun(runOpts, silent);
1293
+ await runPlugins();
1294
+ const { watch } = await import("node:fs");
1295
+ let timer = null;
1296
+ const trigger = (filename) => {
1297
+ if (!filename) return;
1298
+ if (!/\.(ts|tsx|mts|cts)$/.test(filename)) return;
1299
+ if (filename.includes(".kickjs")) return;
1300
+ if (filename.endsWith(".d.ts")) return;
1301
+ if (timer) clearTimeout(timer);
1302
+ timer = setTimeout(() => {
1303
+ safeRun(runOpts, silent);
1304
+ runPlugins();
1305
+ }, 100);
1306
+ };
1307
+ if (forcePolling) {
1308
+ if (!silent) console.log(" kick typegen: polling mode (KICKJS_WATCH_POLLING)");
1309
+ const interval = setInterval(() => {
1310
+ safeRun({
1311
+ ...runOpts,
1312
+ silent: true
1313
+ }, true);
1314
+ }, 2e3);
1315
+ return () => clearInterval(interval);
1316
+ }
1317
+ let watcher;
1318
+ try {
1319
+ watcher = watch(srcDir, { recursive: true }, (_event, filename) => {
1320
+ trigger(filename);
1321
+ });
1322
+ } catch (err) {
1323
+ if (!silent) console.warn(` kick typegen: watch mode unavailable (${err?.message ?? err}). Falling back to polling.`);
1324
+ const interval = setInterval(() => {
1325
+ safeRun({
1326
+ ...runOpts,
1327
+ silent: true
1328
+ }, true);
1329
+ }, 2e3);
1330
+ return () => clearInterval(interval);
1331
+ }
1332
+ return () => {
1333
+ if (timer) clearTimeout(timer);
1334
+ watcher.close();
1335
+ };
1336
+ }
1337
+ /** Run typegen swallowing errors so the watcher loop never dies */
1338
+ async function safeRun(opts, silent) {
1339
+ try {
1340
+ await runTypegen(opts);
1341
+ } catch (err) {
1342
+ if (silent) return;
1343
+ if (err instanceof TokenCollisionError) console.error("\n" + err.message + "\n");
1344
+ else {
1345
+ const msg = err instanceof Error ? err.message : String(err);
1346
+ console.error(` kick typegen failed: ${msg}`);
1347
+ }
1348
+ }
1349
+ }
1447
1350
  //#endregion
1448
- export { runTypegen };
1351
+ export { discoverAssets as a, TokenCollisionError as i, typegen_exports as n, renderAssetTypes as o, watchTypegen as r, scanProject as s, runTypegen as t };
1449
1352
 
1450
- //# sourceMappingURL=typegen-D8MJ2hPX.mjs.map
1353
+ //# sourceMappingURL=typegen-DugZmi-0.mjs.map