@rexeus/typeweaver-gen 0.9.2 → 0.10.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.
package/README.md CHANGED
@@ -27,12 +27,24 @@ Most users don’t depend on this package directly — use the CLI instead:
27
27
  [`@rexeus/typeweaver`](https://github.com/rexeus/typeweaver/tree/main/packages/cli/README.md). If
28
28
  you’re writing a plugin, start here.
29
29
 
30
+ ## 🏷️ Spec naming validation
31
+
32
+ The normalization pipeline validates supported naming formats before generation:
33
+
34
+ - `operationId` should use camelCase (preferred), for example `getUser`.
35
+ - PascalCase `operationId` values are supported for compatibility.
36
+ - snake_case and kebab-case `operationId` values are rejected during normalization.
37
+ - `resourceName` should preferably be a singular noun in camelCase, for example `user` or
38
+ `authSession`.
39
+ - Plural and PascalCase `resourceName` values are supported.
40
+ - snake_case and kebab-case `resourceName` values are rejected during normalization.
41
+
30
42
  ### 🚀 Minimal plugin
31
43
 
32
44
  ```ts
33
45
  import { BasePlugin, type GeneratorContext } from "@rexeus/typeweaver-gen";
34
46
 
35
- export default class MyPlugin extends BasePlugin {
47
+ export class MyPlugin extends BasePlugin {
36
48
  // Give your plugin a unique name
37
49
  name = "my-plugin";
38
50
 
@@ -158,7 +170,7 @@ output.
158
170
  // Resolve the directory of the current module
159
171
  const moduleDir = path.dirname(fileURLToPath(import.meta.url));
160
172
 
161
- export default class MyPlugin extends BasePlugin {
173
+ export class MyPlugin extends BasePlugin {
162
174
  name = "my-plugin";
163
175
 
164
176
  generate(context: GeneratorContext) {
package/dist/index.cjs CHANGED
@@ -27,8 +27,6 @@ let node_fs = require("node:fs");
27
27
  node_fs = __toESM(node_fs);
28
28
  let node_path = require("node:path");
29
29
  node_path = __toESM(node_path);
30
- let ejs = require("ejs");
31
- ejs = __toESM(ejs);
32
30
  //#region src/errors/DerivedResponseCycleError.ts
33
31
  var DerivedResponseCycleError = class extends Error {
34
32
  constructor(responseName) {
@@ -85,6 +83,14 @@ var InvalidDerivedResponseError = class extends Error {
85
83
  }
86
84
  };
87
85
  //#endregion
86
+ //#region src/errors/InvalidOperationIdError.ts
87
+ var InvalidOperationIdError = class extends Error {
88
+ constructor(operationId) {
89
+ super(`Operation ID '${operationId}' is invalid. Use camelCase (preferred) or PascalCase. snake_case and kebab-case are not supported.`);
90
+ this.name = "InvalidOperationIdError";
91
+ }
92
+ };
93
+ //#endregion
88
94
  //#region src/errors/InvalidRequestSchemaError.ts
89
95
  var InvalidRequestSchemaError = class extends Error {
90
96
  constructor(operationId, requestPart) {
@@ -93,6 +99,14 @@ var InvalidRequestSchemaError = class extends Error {
93
99
  }
94
100
  };
95
101
  //#endregion
102
+ //#region src/errors/InvalidResourceNameError.ts
103
+ var InvalidResourceNameError = class extends Error {
104
+ constructor(resourceName) {
105
+ super(`Resource name '${resourceName}' is invalid. Use camelCase singular nouns when possible; PascalCase is also supported. snake_case and kebab-case are not supported.`);
106
+ this.name = "InvalidResourceNameError";
107
+ }
108
+ };
109
+ //#endregion
96
110
  //#region src/errors/MissingDerivedResponseParentError.ts
97
111
  var MissingDerivedResponseParentError = class extends Error {
98
112
  constructor(responseName, parentName) {
@@ -109,6 +123,25 @@ var PathParameterMismatchError = class extends Error {
109
123
  }
110
124
  };
111
125
  //#endregion
126
+ //#region src/helpers/namingUtils.ts
127
+ const CAMEL_CASE_PATTERN = /^[a-z][A-Za-z0-9]*$/;
128
+ const PASCAL_CASE_PATTERN = /^[A-Z][A-Za-z0-9]*$/;
129
+ const isCamelCase = (value) => {
130
+ return CAMEL_CASE_PATTERN.test(value);
131
+ };
132
+ const isPascalCase = (value) => {
133
+ return PASCAL_CASE_PATTERN.test(value);
134
+ };
135
+ const isSupportedIdentifierName = (value) => {
136
+ return isCamelCase(value) || isPascalCase(value);
137
+ };
138
+ const isSupportedOperationId = (value) => {
139
+ return isSupportedIdentifierName(value);
140
+ };
141
+ const isSupportedResourceName = (value) => {
142
+ return isSupportedIdentifierName(value);
143
+ };
144
+ //#endregion
112
145
  //#region src/helpers/routePath.ts
113
146
  const PATH_PARAMETER_PATTERN = /:([A-Za-z0-9_]+)/g;
114
147
  const normalizeRoutePath = (path) => {
@@ -223,6 +256,7 @@ const normalizeOperationResponses = (responses) => {
223
256
  });
224
257
  };
225
258
  const normalizeOperation = (operationIds, routeKeys, operation) => {
259
+ if (!isSupportedOperationId(operation.operationId)) throw new InvalidOperationIdError(operation.operationId);
226
260
  if (operationIds.has(operation.operationId)) throw new DuplicateOperationIdError(operation.operationId);
227
261
  operationIds.add(operation.operationId);
228
262
  const normalizedPath = normalizeRoutePath(operation.path);
@@ -248,6 +282,7 @@ const normalizeSpec = (definition) => {
248
282
  const routeKeys = /* @__PURE__ */ new Set();
249
283
  return {
250
284
  resources: resourceEntries.map(([resourceName, resource]) => {
285
+ if (!isSupportedResourceName(resourceName)) throw new InvalidResourceNameError(resourceName);
251
286
  if (resource.operations.length === 0) throw new EmptyResourceOperationsError(resourceName);
252
287
  return {
253
288
  name: resourceName,
@@ -354,6 +389,37 @@ function relative(from, to) {
354
389
  return posixPath;
355
390
  }
356
391
  //#endregion
392
+ //#region src/helpers/templateEngine.ts
393
+ function escapeHtml(input) {
394
+ return input.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
395
+ }
396
+ function stringifyTemplateValue(value) {
397
+ if (value === void 0 || value === null) return "";
398
+ return String(value);
399
+ }
400
+ function renderTemplate(template, data) {
401
+ const outputChunks = [];
402
+ const expressionPattern = /<%[=-]?[\s\S]*?%>/g;
403
+ let currentIndex = 0;
404
+ let match = expressionPattern.exec(template);
405
+ while (match !== null) {
406
+ const [tag] = match;
407
+ const tagStart = match.index;
408
+ outputChunks.push(`__output.push(${JSON.stringify(template.slice(currentIndex, tagStart))});`);
409
+ if (tag.startsWith("<%=")) {
410
+ const expression = tag.slice(3, -2).trim();
411
+ outputChunks.push(`__output.push(__escape(__stringify(${expression})));`);
412
+ } else if (tag.startsWith("<%-")) {
413
+ const expression = tag.slice(3, -2).trim();
414
+ outputChunks.push(`__output.push(__stringify(${expression}));`);
415
+ } else outputChunks.push(tag.slice(2, -2));
416
+ currentIndex = tagStart + tag.length;
417
+ match = expressionPattern.exec(template);
418
+ }
419
+ outputChunks.push(`__output.push(${JSON.stringify(template.slice(currentIndex))});`);
420
+ return new Function("data", "__escape", "__stringify", `const __output = []; with (data) { ${outputChunks.join("\n")} } return __output.join("");`)(data, escapeHtml, stringifyTemplateValue);
421
+ }
422
+ //#endregion
357
423
  //#region src/plugins/pluginContext.ts
358
424
  function createPluginContextBuilder() {
359
425
  const generatedFiles = /* @__PURE__ */ new Set();
@@ -429,8 +495,7 @@ function createPluginContextBuilder() {
429
495
  },
430
496
  renderTemplate: (templatePath, data) => {
431
497
  const fullTemplatePath = node_path.default.isAbsolute(templatePath) ? templatePath : node_path.default.join(params.templateDir, templatePath);
432
- const template = node_fs.default.readFileSync(fullTemplatePath, "utf8");
433
- return ejs.default.render(template, data);
498
+ return renderTemplate(node_fs.default.readFileSync(fullTemplatePath, "utf8"), data ?? {});
434
499
  },
435
500
  addGeneratedFile: (relativePath) => {
436
501
  generatedFiles.add(relativePath);
@@ -448,6 +513,21 @@ function createPluginContextBuilder() {
448
513
  };
449
514
  }
450
515
  //#endregion
516
+ //#region src/helpers/caseUtils.ts
517
+ function splitWords(input) {
518
+ return input.trim().replace(/[_\-\s]+/g, " ").replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(" ").filter(Boolean).map((word) => word.toLowerCase());
519
+ }
520
+ function capitalize(word) {
521
+ return word.charAt(0).toUpperCase() + word.slice(1);
522
+ }
523
+ function toPascalCase(input) {
524
+ return splitWords(input).map(capitalize).join("");
525
+ }
526
+ function toCamelCase(input) {
527
+ const [firstWord = "", ...remainingWords] = splitWords(input);
528
+ return firstWord + remainingWords.map(capitalize).join("");
529
+ }
530
+ //#endregion
451
531
  //#region src/helpers/routeSort.ts
452
532
  /**
453
533
  * HTTP method priority for route ordering.
@@ -505,7 +585,9 @@ exports.EmptyOperationResponsesError = EmptyOperationResponsesError;
505
585
  exports.EmptyResourceOperationsError = EmptyResourceOperationsError;
506
586
  exports.EmptySpecResourcesError = EmptySpecResourcesError;
507
587
  exports.InvalidDerivedResponseError = InvalidDerivedResponseError;
588
+ exports.InvalidOperationIdError = InvalidOperationIdError;
508
589
  exports.InvalidRequestSchemaError = InvalidRequestSchemaError;
590
+ exports.InvalidResourceNameError = InvalidResourceNameError;
509
591
  exports.MissingDerivedResponseParentError = MissingDerivedResponseParentError;
510
592
  exports.PathParameterMismatchError = PathParameterMismatchError;
511
593
  exports.PluginDependencyError = PluginDependencyError;
@@ -515,6 +597,13 @@ exports.createPluginContextBuilder = createPluginContextBuilder;
515
597
  exports.createPluginRegistry = createPluginRegistry;
516
598
  exports.getMethodPriority = getMethodPriority;
517
599
  exports.getPathParameterNames = getPathParameterNames;
600
+ exports.isCamelCase = isCamelCase;
601
+ exports.isPascalCase = isPascalCase;
602
+ exports.isSupportedOperationId = isSupportedOperationId;
603
+ exports.isSupportedResourceName = isSupportedResourceName;
518
604
  exports.normalizeRoutePath = normalizeRoutePath;
519
605
  exports.normalizeSpec = normalizeSpec;
520
606
  exports.relative = relative;
607
+ exports.renderTemplate = renderTemplate;
608
+ exports.toCamelCase = toCamelCase;
609
+ exports.toPascalCase = toPascalCase;
package/dist/index.d.cts CHANGED
@@ -35,6 +35,11 @@ declare class InvalidDerivedResponseError extends Error {
35
35
  constructor(responseName: string);
36
36
  }
37
37
  //#endregion
38
+ //#region src/errors/InvalidOperationIdError.d.ts
39
+ declare class InvalidOperationIdError extends Error {
40
+ constructor(operationId: string);
41
+ }
42
+ //#endregion
38
43
  //#region src/NormalizedSpec.d.ts
39
44
  type NormalizedSpec = {
40
45
  readonly resources: readonly NormalizedResource[];
@@ -86,6 +91,11 @@ declare class InvalidRequestSchemaError extends Error {
86
91
  constructor(operationId: string, requestPart: keyof NormalizedRequest);
87
92
  }
88
93
  //#endregion
94
+ //#region src/errors/InvalidResourceNameError.d.ts
95
+ declare class InvalidResourceNameError extends Error {
96
+ constructor(resourceName: string);
97
+ }
98
+ //#endregion
89
99
  //#region src/errors/MissingDerivedResponseParentError.d.ts
90
100
  declare class MissingDerivedResponseParentError extends Error {
91
101
  constructor(responseName: string, parentName: string);
@@ -295,6 +305,16 @@ type PluginContextBuilderApi = {
295
305
  };
296
306
  declare function createPluginContextBuilder(): PluginContextBuilderApi;
297
307
  //#endregion
308
+ //#region src/helpers/caseUtils.d.ts
309
+ declare function toPascalCase(input: string): string;
310
+ declare function toCamelCase(input: string): string;
311
+ //#endregion
312
+ //#region src/helpers/namingUtils.d.ts
313
+ declare const isCamelCase: (value: string) => boolean;
314
+ declare const isPascalCase: (value: string) => boolean;
315
+ declare const isSupportedOperationId: (value: string) => boolean;
316
+ declare const isSupportedResourceName: (value: string) => boolean;
317
+ //#endregion
298
318
  //#region src/helpers/path.d.ts
299
319
  declare function relative(from: string, to: string): string;
300
320
  //#endregion
@@ -324,5 +344,8 @@ declare const compareRoutes: (a: {
324
344
  path: string;
325
345
  }) => number;
326
346
  //#endregion
327
- export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidRequestSchemaError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, normalizeRoutePath, normalizeSpec, relative };
347
+ //#region src/helpers/templateEngine.d.ts
348
+ declare function renderTemplate(template: string, data: Record<string, unknown>): string;
349
+ //#endregion
350
+ export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isCamelCase, isPascalCase, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate, toCamelCase, toPascalCase };
328
351
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidOperationIdError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/InvalidResourceNameError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/caseUtils.ts","../src/helpers/namingUtils.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts","../src/helpers/templateEngine.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -35,6 +35,11 @@ declare class InvalidDerivedResponseError extends Error {
35
35
  constructor(responseName: string);
36
36
  }
37
37
  //#endregion
38
+ //#region src/errors/InvalidOperationIdError.d.ts
39
+ declare class InvalidOperationIdError extends Error {
40
+ constructor(operationId: string);
41
+ }
42
+ //#endregion
38
43
  //#region src/NormalizedSpec.d.ts
39
44
  type NormalizedSpec = {
40
45
  readonly resources: readonly NormalizedResource[];
@@ -86,6 +91,11 @@ declare class InvalidRequestSchemaError extends Error {
86
91
  constructor(operationId: string, requestPart: keyof NormalizedRequest);
87
92
  }
88
93
  //#endregion
94
+ //#region src/errors/InvalidResourceNameError.d.ts
95
+ declare class InvalidResourceNameError extends Error {
96
+ constructor(resourceName: string);
97
+ }
98
+ //#endregion
89
99
  //#region src/errors/MissingDerivedResponseParentError.d.ts
90
100
  declare class MissingDerivedResponseParentError extends Error {
91
101
  constructor(responseName: string, parentName: string);
@@ -295,6 +305,16 @@ type PluginContextBuilderApi = {
295
305
  };
296
306
  declare function createPluginContextBuilder(): PluginContextBuilderApi;
297
307
  //#endregion
308
+ //#region src/helpers/caseUtils.d.ts
309
+ declare function toPascalCase(input: string): string;
310
+ declare function toCamelCase(input: string): string;
311
+ //#endregion
312
+ //#region src/helpers/namingUtils.d.ts
313
+ declare const isCamelCase: (value: string) => boolean;
314
+ declare const isPascalCase: (value: string) => boolean;
315
+ declare const isSupportedOperationId: (value: string) => boolean;
316
+ declare const isSupportedResourceName: (value: string) => boolean;
317
+ //#endregion
298
318
  //#region src/helpers/path.d.ts
299
319
  declare function relative(from: string, to: string): string;
300
320
  //#endregion
@@ -324,5 +344,8 @@ declare const compareRoutes: (a: {
324
344
  path: string;
325
345
  }) => number;
326
346
  //#endregion
327
- export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidRequestSchemaError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, normalizeRoutePath, normalizeSpec, relative };
347
+ //#region src/helpers/templateEngine.d.ts
348
+ declare function renderTemplate(template: string, data: Record<string, unknown>): string;
349
+ //#endregion
350
+ export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isCamelCase, isPascalCase, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate, toCamelCase, toPascalCase };
328
351
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidOperationIdError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/InvalidResourceNameError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/caseUtils.ts","../src/helpers/namingUtils.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts","../src/helpers/templateEngine.ts"],"mappings":";;;cAAa,yBAAA,SAAkC,KAAA;cAC1B,YAAA;AAAA;;;cCDR,yBAAA,SAAkC,KAAA;cAC1B,WAAA;AAAA;;;cCDR,mBAAA,SAA4B,KAAA;cACpB,MAAA,UAAgB,IAAA,UAAc,cAAA;AAAA;;;cCDtC,4BAAA,SAAqC,KAAA;cAC7B,WAAA;AAAA;;;cCDR,4BAAA,SAAqC,KAAA;cAC7B,YAAA;AAAA;;;cCDR,uBAAA,SAAgC,KAAA;EAAA,WAAA,CAAA;AAAA;;;cCAhC,2BAAA,SAAoC,KAAA;cAC5B,YAAA;AAAA;;;cCDR,uBAAA,SAAgC,KAAA;cACxB,WAAA;AAAA;;;KCQT,cAAA;EAAA,SACD,SAAA,WAAoB,kBAAA;EAAA,SACpB,SAAA,WAAoB,kBAAA;AAAA;AAAA,KAGnB,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,UAAA,WAAqB,mBAAA;AAAA;AAAA,KAGpB,mBAAA;EAAA,SACD,WAAA;EAAA,SACA,MAAA,EAAQ,UAAA;EAAA,SACR,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA,GAAU,iBAAA;EAAA,SACV,SAAA,WAAoB,uBAAA;AAAA;AAAA,KAGnB,iBAAA;EAAA,SACD,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,eAAA;EAAA,SACR,KAAA,GAAQ,eAAA;EAAA,SACR,IAAA,GAAO,cAAA;AAAA;AAAA,KAGN,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,UAAA,EAAY,cAAA;EAAA,SACZ,cAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,IAAA,GAAO,cAAA;EAAA,SACP,IAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,gCAAA;EAAA,SACD,YAAA;EAAA,SACA,MAAA;AAAA;AAAA,KAGC,6BAAA;EAAA,SACD,YAAA;EAAA,SACA,MAAA;EAAA,SACA,QAAA,EAAU,kBAAA;AAAA;AAAA,KAGT,uBAAA,GACR,gCAAA,GACA,6BAAA;;;cC3DS,yBAAA,SAAkC,KAAA;cAE3C,WAAA,UACA,WAAA,QAAmB,iBAAA;AAAA;;;cCLV,wBAAA,SAAiC,KAAA;cACzB,YAAA;AAAA;;;cCDR,iCAAA,SAA0C,KAAA;cAClC,YAAA,UAAsB,UAAA;AAAA;;;cCD9B,0BAAA,SAAmC,KAAA;cAE5C,WAAA,UACA,IAAA,UACA,UAAA,qBACA,aAAA;AAAA;;;cCgLS,aAAA,GAAiB,UAAA,EAAY,cAAA,KAAiB,cAAA;;;;;AbrL3D;KcKY,YAAA,GAAe,MAAA;;;;KAKf,aAAA;EAAA,SACD,SAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGP,oBAAA;EAAA,SACD,SAAA;EAAA,SACA,WAAA;EAAA,SACA,eAAA;EAAA,SACA,YAAA;EAAA,SACA,gBAAA;EAAA,SACA,qBAAA;EAAA,SACA,yBAAA;EAAA,SACA,sBAAA;EAAA,SACA,0BAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;AAAA;;AZ3BX;;KYiCY,gBAAA,GAAmB,aAAA;EAAA,SACpB,cAAA,EAAgB,cAAA;EAAA,SAChB,WAAA;EAAA,SACA,OAAA;EAAA,SACA,kBAAA;EAAA,SACA,aAAA;EAAA,SAEA,oBAAA,GAAuB,YAAA,aAAyB,kBAAA;EAAA,SAChD,8BAAA,GAAiC,YAAA;EAAA,SACjC,8BAAA,GAAiC,MAAA;IAAA,SAC/B,WAAA;IAAA,SACA,YAAA;EAAA;EAAA,SAEF,iBAAA,GAAoB,MAAA;IAAA,SAClB,WAAA;EAAA;EAAA,SAEF,8BAAA,GAAiC,MAAA;IAAA,SAC/B,YAAA;IAAA,SACA,WAAA;EAAA;EAAA,SAEF,uBAAA,GAA0B,MAAA;IAAA,SACxB,YAAA;IAAA,SACA,WAAA;EAAA,MACL,oBAAA;EAAA,SACG,oBAAA,GAAuB,YAAA;EAAA,SACvB,SAAA,GAAY,YAAA,UAAsB,OAAA;EAAA,SAClC,cAAA,GAAiB,YAAA,UAAsB,IAAA;EAAA,SACvC,gBAAA,GAAmB,YAAA;EAAA,SACnB,iBAAA;AAAA;;;;KAMC,cAAA;EAAA,SACD,IAAA;AAAA;;ATpEX;;KS0EY,gBAAA,GAAmB,cAAA;ET1Ec;;;;ES+E3C,UAAA,EAAY,OAAA,EAAS,aAAA,GAAgB,OAAA;ER/E1B;;;;EQqFX,gBAAA,EACE,cAAA,EAAgB,cAAA,GACf,OAAA,CAAQ,cAAA,IAAkB,cAAA;;;;;EAM7B,QAAA,EAAU,OAAA,EAAS,gBAAA,GAAmB,OAAA;;;AP7FxC;;EOmGE,QAAA,EAAU,OAAA,EAAS,aAAA,GAAgB,OAAA;AAAA;;;;KAMzB,iBAAA,QAAyB,MAAA,GAAS,YAAA,KAAiB,gBAAA;;;;KAKnD,YAAA;EACV,OAAA,EAAS,iBAAA;AAAA;;;;KAMC,kBAAA;EACV,IAAA;EACA,MAAA,EAAQ,gBAAA;EACR,MAAA,GAAS,YAAA;AAAA;AN1GX;;;AAAA,KMgHY,gBAAA;EACV,KAAA;EACA,MAAA;EACA,OAAA,sBAA6B,YAAA;EAC7B,MAAA;EACA,KAAA;AAAA;;;;cAMW,eAAA,SAAwB,KAAA;EAE1B,UAAA;cAAA,UAAA,UACP,OAAA;AAAA;;;;cAUS,qBAAA,SAA8B,KAAA;EAEhC,UAAA;EACA,iBAAA;cADA,UAAA,UACA,iBAAA;AAAA;;;;AdzJX;;;uBecsB,UAAA,YAAsB,gBAAA;EAAA,SACjC,IAAA;EACT,WAAA;EACA,MAAA;EACA,OAAA;EAAA,UAEU,MAAA,EAAQ,YAAA;cAEN,MAAA,GAAQ,YAAA;;;AdtBtB;Ec6BQ,UAAA,CAAW,QAAA,EAAU,aAAA,GAAgB,OAAA;;;;EAO3C,gBAAA,CAAiB,cAAA,EAAgB,cAAA,GAAiB,cAAA;EdnC/B;;;EAAA,Sc0CV,QAAA,CAAS,OAAA,EAAS,gBAAA,GAAmB,OAAA;;;Ab3ChD;EagDQ,QAAA,CAAS,QAAA,EAAU,aAAA,GAAgB,OAAA;EAAA,UAI/B,YAAA,CACR,OAAA,EAAS,gBAAA,EACT,YAAA,UACA,YAAA;AAAA;;;KCrDQ,iBAAA;EAAA,SACD,QAAA,GAAW,MAAA,EAAQ,gBAAA,EAAkB,MAAA;EAAA,SACrC,GAAA,GAAM,IAAA,aAAiB,kBAAA;EAAA,SACvB,MAAA,QAAc,kBAAA;EAAA,SACd,GAAA,GAAM,IAAA;EAAA,SACN,KAAA;AAAA;AAAA,iBAGK,oBAAA,CAAA,GAAwB,iBAAA;;;KCH5B,uBAAA;EAAA,SACD,mBAAA,GAAsB,MAAA;IAC7B,SAAA;IACA,QAAA;IACA,MAAA,EAAQ,YAAA;EAAA,MACJ,aAAA;EAAA,SACG,sBAAA,GAAyB,MAAA;IAAA,SACvB,SAAA;IAAA,SACA,QAAA;IAAA,SACA,MAAA,EAAQ,YAAA;IAAA,SACR,cAAA,EAAgB,cAAA;IAAA,SAChB,WAAA;IAAA,SACA,OAAA;IAAA,SACA,kBAAA;IAAA,SACA,aAAA;EAAA,MACL,gBAAA;EAAA,SACG,iBAAA;EAAA,SACA,mBAAA;AAAA;AAAA,iBAGK,0BAAA,CAAA,GAA8B,uBAAA;;;iBCZ9B,YAAA,CAAa,KAAA;AAAA,iBAIb,WAAA,CAAY,KAAA;;;cChBf,WAAA,GAAe,KAAA;AAAA,cAIf,YAAA,GAAgB,KAAA;AAAA,cAQhB,sBAAA,GAA0B,KAAA;AAAA,cAI1B,uBAAA,GAA2B,KAAA;;;iBCjBxB,QAAA,CAAS,IAAA,UAAc,EAAA;;;cCA1B,kBAAA,GAAsB,IAAA;AAAA,cAUtB,qBAAA,GAAyB,IAAA;;;;;;ArBZtC;csBoBa,iBAAA,GAAqB,MAAA;;;;;;;;;cA4BrB,aAAA,GACX,CAAA;EAAK,MAAA;EAAgB,IAAA;AAAA,GACrB,CAAA;EAAK,MAAA;EAAgB,IAAA;AAAA;;;iBCjCP,cAAA,CACd,QAAA,UACA,IAAA,EAAM,MAAA"}
package/dist/index.mjs CHANGED
@@ -2,7 +2,6 @@ import { HttpMethod, HttpStatusCodeNameMap, isNamedResponseDefinition, validateU
2
2
  import { z } from "zod";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
- import ejs from "ejs";
6
5
  //#region src/errors/DerivedResponseCycleError.ts
7
6
  var DerivedResponseCycleError = class extends Error {
8
7
  constructor(responseName) {
@@ -59,6 +58,14 @@ var InvalidDerivedResponseError = class extends Error {
59
58
  }
60
59
  };
61
60
  //#endregion
61
+ //#region src/errors/InvalidOperationIdError.ts
62
+ var InvalidOperationIdError = class extends Error {
63
+ constructor(operationId) {
64
+ super(`Operation ID '${operationId}' is invalid. Use camelCase (preferred) or PascalCase. snake_case and kebab-case are not supported.`);
65
+ this.name = "InvalidOperationIdError";
66
+ }
67
+ };
68
+ //#endregion
62
69
  //#region src/errors/InvalidRequestSchemaError.ts
63
70
  var InvalidRequestSchemaError = class extends Error {
64
71
  constructor(operationId, requestPart) {
@@ -67,6 +74,14 @@ var InvalidRequestSchemaError = class extends Error {
67
74
  }
68
75
  };
69
76
  //#endregion
77
+ //#region src/errors/InvalidResourceNameError.ts
78
+ var InvalidResourceNameError = class extends Error {
79
+ constructor(resourceName) {
80
+ super(`Resource name '${resourceName}' is invalid. Use camelCase singular nouns when possible; PascalCase is also supported. snake_case and kebab-case are not supported.`);
81
+ this.name = "InvalidResourceNameError";
82
+ }
83
+ };
84
+ //#endregion
70
85
  //#region src/errors/MissingDerivedResponseParentError.ts
71
86
  var MissingDerivedResponseParentError = class extends Error {
72
87
  constructor(responseName, parentName) {
@@ -83,6 +98,25 @@ var PathParameterMismatchError = class extends Error {
83
98
  }
84
99
  };
85
100
  //#endregion
101
+ //#region src/helpers/namingUtils.ts
102
+ const CAMEL_CASE_PATTERN = /^[a-z][A-Za-z0-9]*$/;
103
+ const PASCAL_CASE_PATTERN = /^[A-Z][A-Za-z0-9]*$/;
104
+ const isCamelCase = (value) => {
105
+ return CAMEL_CASE_PATTERN.test(value);
106
+ };
107
+ const isPascalCase = (value) => {
108
+ return PASCAL_CASE_PATTERN.test(value);
109
+ };
110
+ const isSupportedIdentifierName = (value) => {
111
+ return isCamelCase(value) || isPascalCase(value);
112
+ };
113
+ const isSupportedOperationId = (value) => {
114
+ return isSupportedIdentifierName(value);
115
+ };
116
+ const isSupportedResourceName = (value) => {
117
+ return isSupportedIdentifierName(value);
118
+ };
119
+ //#endregion
86
120
  //#region src/helpers/routePath.ts
87
121
  const PATH_PARAMETER_PATTERN = /:([A-Za-z0-9_]+)/g;
88
122
  const normalizeRoutePath = (path) => {
@@ -197,6 +231,7 @@ const normalizeOperationResponses = (responses) => {
197
231
  });
198
232
  };
199
233
  const normalizeOperation = (operationIds, routeKeys, operation) => {
234
+ if (!isSupportedOperationId(operation.operationId)) throw new InvalidOperationIdError(operation.operationId);
200
235
  if (operationIds.has(operation.operationId)) throw new DuplicateOperationIdError(operation.operationId);
201
236
  operationIds.add(operation.operationId);
202
237
  const normalizedPath = normalizeRoutePath(operation.path);
@@ -222,6 +257,7 @@ const normalizeSpec = (definition) => {
222
257
  const routeKeys = /* @__PURE__ */ new Set();
223
258
  return {
224
259
  resources: resourceEntries.map(([resourceName, resource]) => {
260
+ if (!isSupportedResourceName(resourceName)) throw new InvalidResourceNameError(resourceName);
225
261
  if (resource.operations.length === 0) throw new EmptyResourceOperationsError(resourceName);
226
262
  return {
227
263
  name: resourceName,
@@ -328,6 +364,37 @@ function relative(from, to) {
328
364
  return posixPath;
329
365
  }
330
366
  //#endregion
367
+ //#region src/helpers/templateEngine.ts
368
+ function escapeHtml(input) {
369
+ return input.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
370
+ }
371
+ function stringifyTemplateValue(value) {
372
+ if (value === void 0 || value === null) return "";
373
+ return String(value);
374
+ }
375
+ function renderTemplate(template, data) {
376
+ const outputChunks = [];
377
+ const expressionPattern = /<%[=-]?[\s\S]*?%>/g;
378
+ let currentIndex = 0;
379
+ let match = expressionPattern.exec(template);
380
+ while (match !== null) {
381
+ const [tag] = match;
382
+ const tagStart = match.index;
383
+ outputChunks.push(`__output.push(${JSON.stringify(template.slice(currentIndex, tagStart))});`);
384
+ if (tag.startsWith("<%=")) {
385
+ const expression = tag.slice(3, -2).trim();
386
+ outputChunks.push(`__output.push(__escape(__stringify(${expression})));`);
387
+ } else if (tag.startsWith("<%-")) {
388
+ const expression = tag.slice(3, -2).trim();
389
+ outputChunks.push(`__output.push(__stringify(${expression}));`);
390
+ } else outputChunks.push(tag.slice(2, -2));
391
+ currentIndex = tagStart + tag.length;
392
+ match = expressionPattern.exec(template);
393
+ }
394
+ outputChunks.push(`__output.push(${JSON.stringify(template.slice(currentIndex))});`);
395
+ return new Function("data", "__escape", "__stringify", `const __output = []; with (data) { ${outputChunks.join("\n")} } return __output.join("");`)(data, escapeHtml, stringifyTemplateValue);
396
+ }
397
+ //#endregion
331
398
  //#region src/plugins/pluginContext.ts
332
399
  function createPluginContextBuilder() {
333
400
  const generatedFiles = /* @__PURE__ */ new Set();
@@ -403,8 +470,7 @@ function createPluginContextBuilder() {
403
470
  },
404
471
  renderTemplate: (templatePath, data) => {
405
472
  const fullTemplatePath = path.isAbsolute(templatePath) ? templatePath : path.join(params.templateDir, templatePath);
406
- const template = fs.readFileSync(fullTemplatePath, "utf8");
407
- return ejs.render(template, data);
473
+ return renderTemplate(fs.readFileSync(fullTemplatePath, "utf8"), data ?? {});
408
474
  },
409
475
  addGeneratedFile: (relativePath) => {
410
476
  generatedFiles.add(relativePath);
@@ -422,6 +488,21 @@ function createPluginContextBuilder() {
422
488
  };
423
489
  }
424
490
  //#endregion
491
+ //#region src/helpers/caseUtils.ts
492
+ function splitWords(input) {
493
+ return input.trim().replace(/[_\-\s]+/g, " ").replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(" ").filter(Boolean).map((word) => word.toLowerCase());
494
+ }
495
+ function capitalize(word) {
496
+ return word.charAt(0).toUpperCase() + word.slice(1);
497
+ }
498
+ function toPascalCase(input) {
499
+ return splitWords(input).map(capitalize).join("");
500
+ }
501
+ function toCamelCase(input) {
502
+ const [firstWord = "", ...remainingWords] = splitWords(input);
503
+ return firstWord + remainingWords.map(capitalize).join("");
504
+ }
505
+ //#endregion
425
506
  //#region src/helpers/routeSort.ts
426
507
  /**
427
508
  * HTTP method priority for route ordering.
@@ -471,6 +552,6 @@ const compareRoutes = (a, b) => {
471
552
  return getMethodPriority(a.method) - getMethodPriority(b.method);
472
553
  };
473
554
  //#endregion
474
- export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, InvalidDerivedResponseError, InvalidRequestSchemaError, MissingDerivedResponseParentError, PathParameterMismatchError, PluginDependencyError, PluginLoadError, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, normalizeRoutePath, normalizeSpec, relative };
555
+ export { BasePlugin, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, PathParameterMismatchError, PluginDependencyError, PluginLoadError, compareRoutes, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isCamelCase, isPascalCase, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate, toCamelCase, toPascalCase };
475
556
 
476
557
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/helpers/routePath.ts","../src/validation/derivedResponseValidation.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/helpers/path.ts","../src/plugins/pluginContext.ts","../src/helpers/routeSort.ts"],"sourcesContent":["export class DerivedResponseCycleError extends Error {\n public constructor(responseName: string) {\n super(`Derived response '${responseName}' contains a cyclic lineage.`);\n this.name = \"DerivedResponseCycleError\";\n }\n}\n","export class DuplicateOperationIdError extends Error {\n public constructor(operationId: string) {\n super(\n `Operation ID '${operationId}' must be globally unique within a spec.`\n );\n this.name = \"DuplicateOperationIdError\";\n }\n}\n","export class DuplicateRouteError extends Error {\n public constructor(method: string, path: string, normalizedPath: string) {\n super(\n `Route '${method} ${path}' conflicts with an existing route using normalized path '${normalizedPath}'.`\n );\n this.name = \"DuplicateRouteError\";\n }\n}\n","export class EmptyOperationResponsesError extends Error {\n public constructor(operationId: string) {\n super(`Operation '${operationId}' must declare at least one response.`);\n this.name = \"EmptyOperationResponsesError\";\n }\n}\n","export class EmptyResourceOperationsError extends Error {\n public constructor(resourceName: string) {\n super(`Resource '${resourceName}' must contain at least one operation.`);\n this.name = \"EmptyResourceOperationsError\";\n }\n}\n","export class EmptySpecResourcesError extends Error {\n public constructor() {\n super(\"Spec definition must contain at least one resource.\");\n this.name = \"EmptySpecResourcesError\";\n }\n}\n","export class InvalidDerivedResponseError extends Error {\n public constructor(responseName: string) {\n super(\n `Derived response '${responseName}' contains invalid lineage metadata.`\n );\n this.name = \"InvalidDerivedResponseError\";\n }\n}\n","import type { NormalizedRequest } from \"../NormalizedSpec\";\n\nexport class InvalidRequestSchemaError extends Error {\n public constructor(\n operationId: string,\n requestPart: keyof NormalizedRequest\n ) {\n super(\n `Operation '${operationId}' has an invalid request.${requestPart} schema definition.`\n );\n this.name = \"InvalidRequestSchemaError\";\n }\n}\n","export class MissingDerivedResponseParentError extends Error {\n public constructor(responseName: string, parentName: string) {\n super(\n `Derived response '${responseName}' references missing canonical parent '${parentName}'.`\n );\n this.name = \"MissingDerivedResponseParentError\";\n }\n}\n","export class PathParameterMismatchError extends Error {\n public constructor(\n operationId: string,\n path: string,\n pathParams: readonly string[],\n requestParams: readonly string[]\n ) {\n super(\n `Operation '${operationId}' has mismatched path parameters for '${path}'. Path params: [${pathParams.join(\n \", \"\n )}], request.param keys: [${requestParams.join(\", \")}].`\n );\n this.name = \"PathParameterMismatchError\";\n }\n}\n","const PATH_PARAMETER_PATTERN = /:([A-Za-z0-9_]+)/g;\n\nexport const normalizeRoutePath = (path: string): string => {\n const segments = path.split(\"/\").filter(Boolean);\n\n if (segments.length === 0) {\n return \"/\";\n }\n\n return `/${segments.map(segment => (segment.startsWith(\":\") ? \":\" : segment)).join(\"/\")}`;\n};\n\nexport const getPathParameterNames = (path: string): string[] => {\n return Array.from(\n path.matchAll(PATH_PARAMETER_PATTERN),\n match => match[1] as string\n );\n};\n","import {\n HttpStatusCodeNameMap,\n isNamedResponseDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport type {\n ResponseDefinition,\n SpecDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport {\n DerivedResponseCycleError,\n InvalidDerivedResponseError,\n MissingDerivedResponseParentError,\n} from \"../errors\";\nimport type { NormalizedResponse } from \"../NormalizedSpec\";\n\nexport const validateDerivedResponseMetadata = (\n response: ResponseDefinition\n): void => {\n const derived = response.derived;\n\n if (derived === undefined) {\n return;\n }\n\n if (derived.parentName === response.name) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n if (derived.lineage.length === 0) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (derived.lineage.at(-1) !== response.name) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (derived.lineage.length !== derived.depth) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (new Set(derived.lineage).size !== derived.lineage.length) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n if (derived.depth > 1 && derived.lineage.at(-2) !== derived.parentName) {\n throw new InvalidDerivedResponseError(response.name);\n }\n};\n\nexport const collectCanonicalResponseDefinitions = (\n definition: SpecDefinition\n): Map<string, ResponseDefinition> => {\n const canonicalResponses = new Map<string, ResponseDefinition>();\n\n for (const resource of Object.values(definition.resources)) {\n for (const operation of resource.operations) {\n for (const response of operation.responses) {\n if (!isNamedResponseDefinition(response)) {\n continue;\n }\n\n validateDerivedResponseMetadata(response);\n\n canonicalResponses.set(response.name, response);\n }\n }\n }\n\n return canonicalResponses;\n};\n\nexport const getDerivedResponseChain = (\n response: ResponseDefinition,\n canonicalResponses: ReadonlyMap<string, ResponseDefinition>\n): readonly string[] => {\n const chain: string[] = [response.name];\n const visitedResponseNames = new Set(chain);\n let parentName = response.derived?.parentName;\n\n while (parentName !== undefined) {\n if (visitedResponseNames.has(parentName)) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n const parentResponse = canonicalResponses.get(parentName);\n\n if (parentResponse === undefined) {\n throw new MissingDerivedResponseParentError(response.name, parentName);\n }\n\n chain.unshift(parentResponse.name);\n visitedResponseNames.add(parentResponse.name);\n parentName = parentResponse.derived?.parentName;\n }\n\n return chain;\n};\n\nexport const validateDerivedResponseGraph = (\n canonicalResponses: ReadonlyMap<string, ResponseDefinition>\n): void => {\n for (const response of canonicalResponses.values()) {\n if (response.derived === undefined) {\n continue;\n }\n\n const chain = getDerivedResponseChain(response, canonicalResponses);\n const materializedLineage = chain.slice(1);\n\n if (response.derived.depth !== materializedLineage.length) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (\n materializedLineage.length !== response.derived.lineage.length ||\n materializedLineage.some(\n (lineageEntry, index) =>\n lineageEntry !== response.derived?.lineage[index]\n )\n ) {\n throw new InvalidDerivedResponseError(response.name);\n }\n }\n};\n\nexport const normalizeResponseDefinition = (\n response: ResponseDefinition\n): NormalizedResponse => {\n return {\n name: response.name,\n statusCode: response.statusCode,\n statusCodeName: HttpStatusCodeNameMap[response.statusCode],\n description: response.description,\n header: response.header,\n body: response.body,\n kind: response.derived === undefined ? \"response\" : \"derived-response\",\n derivedFrom: response.derived?.parentName,\n lineage: response.derived?.lineage,\n depth: response.derived?.depth,\n };\n};\n\nexport const collectCanonicalResponses = (\n definition: SpecDefinition\n): Map<string, NormalizedResponse> => {\n const canonicalResponseDefinitions =\n collectCanonicalResponseDefinitions(definition);\n\n validateDerivedResponseGraph(canonicalResponseDefinitions);\n\n return new Map(\n Array.from(\n canonicalResponseDefinitions.entries(),\n ([responseName, response]) => [\n responseName,\n normalizeResponseDefinition(response),\n ]\n )\n );\n};\n","import {\n isNamedResponseDefinition,\n validateUniqueResponseNames,\n} from \"@rexeus/typeweaver-core\";\nimport type {\n RequestDefinition,\n ResourceDefinition,\n ResponseDefinition,\n SpecDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport { z } from \"zod\";\nimport {\n DuplicateOperationIdError,\n DuplicateRouteError,\n EmptyOperationResponsesError,\n EmptyResourceOperationsError,\n EmptySpecResourcesError,\n InvalidRequestSchemaError,\n PathParameterMismatchError,\n} from \"./errors\";\nimport { getPathParameterNames, normalizeRoutePath } from \"./helpers/routePath\";\nimport {\n collectCanonicalResponses,\n normalizeResponseDefinition,\n} from \"./validation\";\nimport type {\n NormalizedOperation,\n NormalizedRequest,\n NormalizedResponseUsage,\n NormalizedSpec,\n} from \"./NormalizedSpec\";\n\nconst isZodType = (schema: unknown): schema is z.ZodType => {\n return schema instanceof z.ZodType;\n};\n\nconst isZodObject = (\n schema: unknown\n): schema is z.ZodObject<z.core.$ZodShape> => {\n return schema instanceof z.ZodObject;\n};\n\nconst validateRequestSchema = (\n operationId: string,\n requestPart: keyof NormalizedRequest,\n schema: unknown\n): void => {\n if (!isZodType(schema)) {\n throw new InvalidRequestSchemaError(operationId, requestPart);\n }\n\n if (requestPart === \"param\" && !isZodObject(schema)) {\n throw new InvalidRequestSchemaError(operationId, requestPart);\n }\n};\n\nconst validateRequest = (\n operationId: string,\n path: string,\n request: RequestDefinition\n): NormalizedRequest | undefined => {\n if (request.header !== undefined) {\n validateRequestSchema(operationId, \"header\", request.header);\n }\n\n if (request.param !== undefined) {\n validateRequestSchema(operationId, \"param\", request.param);\n }\n\n if (request.query !== undefined) {\n validateRequestSchema(operationId, \"query\", request.query);\n }\n\n if (request.body !== undefined) {\n validateRequestSchema(operationId, \"body\", request.body);\n }\n\n const pathParams = getPathParameterNames(path);\n const requestParams =\n request.param === undefined ? [] : Object.keys(request.param.shape);\n\n if (\n pathParams.length !== requestParams.length ||\n pathParams.some(pathParam => !requestParams.includes(pathParam))\n ) {\n throw new PathParameterMismatchError(\n operationId,\n path,\n pathParams,\n requestParams\n );\n }\n\n if (\n request.header === undefined &&\n request.param === undefined &&\n request.query === undefined &&\n request.body === undefined\n ) {\n return undefined;\n }\n\n return {\n header: request.header,\n param: request.param,\n query: request.query,\n body: request.body,\n };\n};\n\nconst normalizeOperationResponses = (\n responses: readonly ResponseDefinition[]\n): NormalizedResponseUsage[] => {\n return responses.map(response => {\n if (isNamedResponseDefinition(response)) {\n return {\n responseName: response.name,\n source: \"canonical\",\n };\n }\n\n return {\n responseName: response.name,\n source: \"inline\",\n response: normalizeResponseDefinition(response),\n };\n });\n};\n\nconst normalizeOperation = (\n operationIds: Set<string>,\n routeKeys: Set<string>,\n operation: ResourceDefinition[\"operations\"][number]\n): NormalizedOperation => {\n if (operationIds.has(operation.operationId)) {\n throw new DuplicateOperationIdError(operation.operationId);\n }\n\n operationIds.add(operation.operationId);\n\n const normalizedPath = normalizeRoutePath(operation.path);\n const routeKey = `${operation.method}:${normalizedPath}`;\n\n if (routeKeys.has(routeKey)) {\n throw new DuplicateRouteError(\n operation.method,\n operation.path,\n normalizedPath\n );\n }\n\n routeKeys.add(routeKey);\n\n if (operation.responses.length === 0) {\n throw new EmptyOperationResponsesError(operation.operationId);\n }\n\n return {\n operationId: operation.operationId,\n method: operation.method,\n path: operation.path,\n summary: operation.summary,\n request: validateRequest(\n operation.operationId,\n operation.path,\n operation.request\n ),\n responses: normalizeOperationResponses(operation.responses),\n };\n};\n\nexport const normalizeSpec = (definition: SpecDefinition): NormalizedSpec => {\n const resourceEntries = Object.entries(definition.resources);\n\n if (resourceEntries.length === 0) {\n throw new EmptySpecResourcesError();\n }\n\n validateUniqueResponseNames(definition.resources);\n const canonicalResponses = collectCanonicalResponses(definition);\n const operationIds = new Set<string>();\n const routeKeys = new Set<string>();\n\n return {\n resources: resourceEntries.map(([resourceName, resource]) => {\n if (resource.operations.length === 0) {\n throw new EmptyResourceOperationsError(resourceName);\n }\n\n return {\n name: resourceName,\n operations: resource.operations.map(operation =>\n normalizeOperation(operationIds, routeKeys, operation)\n ),\n };\n }),\n responses: Array.from(canonicalResponses.values()),\n };\n};\n","import type { NormalizedResponse, NormalizedSpec } from \"../NormalizedSpec\";\n\n/**\n * Configuration for a typeweaver plugin\n */\nexport type PluginConfig = Record<string, unknown>;\n\n/**\n * Context provided to plugins during initialization and finalization\n */\nexport type PluginContext = {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n};\n\nexport type OperationOutputPaths = {\n readonly outputDir: string;\n readonly requestFile: string;\n readonly requestFileName: string;\n readonly responseFile: string;\n readonly responseFileName: string;\n readonly requestValidationFile: string;\n readonly requestValidationFileName: string;\n readonly responseValidationFile: string;\n readonly responseValidationFileName: string;\n readonly clientFile: string;\n readonly clientFileName: string;\n};\n\n/**\n * Context provided to plugins during generation\n */\nexport type GeneratorContext = PluginContext & {\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n\n readonly getCanonicalResponse: (responseName: string) => NormalizedResponse;\n readonly getCanonicalResponseOutputFile: (responseName: string) => string;\n readonly getCanonicalResponseImportPath: (params: {\n readonly importerDir: string;\n readonly responseName: string;\n }) => string;\n readonly getSpecImportPath: (params: {\n readonly importerDir: string;\n }) => string;\n readonly getOperationDefinitionAccessor: (params: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => string;\n readonly getOperationOutputPaths: (params: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => OperationOutputPaths;\n readonly getResourceOutputDir: (resourceName: string) => string;\n readonly writeFile: (relativePath: string, content: string) => void;\n readonly renderTemplate: (templatePath: string, data: unknown) => string;\n readonly addGeneratedFile: (relativePath: string) => void;\n readonly getGeneratedFiles: () => string[];\n};\n\n/**\n * Plugin metadata\n */\nexport type PluginMetadata = {\n readonly name: string;\n};\n\n/**\n * typeweaver plugin interface\n */\nexport type TypeweaverPlugin = PluginMetadata & {\n /**\n * Initialize the plugin\n * Called before any generation happens\n */\n initialize?(context: PluginContext): Promise<void> | void;\n\n /**\n * Collect and transform resources\n * Allows plugins to modify the resource collection\n */\n collectResources?(\n normalizedSpec: NormalizedSpec\n ): Promise<NormalizedSpec> | NormalizedSpec;\n\n /**\n * Main generation logic\n * Called with all resources and utilities\n */\n generate?(context: GeneratorContext): Promise<void> | void;\n\n /**\n * Finalize the plugin\n * Called after all generation is complete\n */\n finalize?(context: PluginContext): Promise<void> | void;\n};\n\n/**\n * Plugin constructor type\n */\nexport type PluginConstructor = new (config?: PluginConfig) => TypeweaverPlugin;\n\n/**\n * Plugin module export\n */\nexport type PluginModule = {\n default: PluginConstructor;\n};\n\n/**\n * Plugin registration entry\n */\nexport type PluginRegistration = {\n name: string;\n plugin: TypeweaverPlugin;\n config?: PluginConfig;\n};\n\n/**\n * typeweaver configuration\n */\nexport type TypeweaverConfig = {\n input: string;\n output: string;\n plugins?: (string | [string, PluginConfig])[];\n format?: boolean;\n clean?: boolean;\n};\n\n/**\n * Plugin loading error\n */\nexport class PluginLoadError extends Error {\n constructor(\n public pluginName: string,\n message: string\n ) {\n super(`Failed to load plugin '${pluginName}': ${message}`);\n this.name = \"PluginLoadError\";\n }\n}\n\n/**\n * Plugin dependency error\n */\nexport class PluginDependencyError extends Error {\n constructor(\n public pluginName: string,\n public missingDependency: string\n ) {\n super(\n `Plugin '${pluginName}' depends on '${missingDependency}' which is not loaded`\n );\n this.name = \"PluginDependencyError\";\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { NormalizedSpec } from \"../NormalizedSpec\";\nimport type {\n GeneratorContext,\n PluginConfig,\n PluginContext,\n TypeweaverPlugin,\n} from \"./types\";\n\n/**\n * Base class for typeweaver plugins\n * Provides default implementations and common utilities\n */\nexport abstract class BasePlugin implements TypeweaverPlugin {\n abstract name: string;\n description?: string;\n author?: string;\n depends?: string[];\n\n protected config: PluginConfig;\n\n constructor(config: PluginConfig = {}) {\n this.config = config;\n }\n\n /**\n * Default implementation - override in subclasses if needed\n */\n async initialize(_context: PluginContext): Promise<void> {\n // Default: no initialization needed\n }\n\n /**\n * Default implementation - override in subclasses if needed\n */\n collectResources(normalizedSpec: NormalizedSpec): NormalizedSpec {\n return normalizedSpec;\n }\n\n /**\n * Main generation logic - must be implemented by subclasses\n */\n abstract generate(context: GeneratorContext): Promise<void> | void;\n\n /**\n * Default implementation - override in subclasses if needed\n */\n async finalize(_context: PluginContext): Promise<void> {\n // Default: no finalization needed\n }\n\n protected copyLibFiles(\n context: GeneratorContext,\n libSourceDir: string,\n libNamespace: string\n ): void {\n if (!fs.existsSync(libSourceDir)) return;\n\n const libDir = path.join(context.outputDir, \"lib\", libNamespace);\n\n fs.cpSync(libSourceDir, libDir, { recursive: true });\n\n const libIndexPath = path.join(\"lib\", libNamespace, \"index.ts\");\n if (fs.existsSync(path.join(libDir, \"index.ts\"))) {\n context.addGeneratedFile(libIndexPath);\n }\n }\n}\n","import type { PluginRegistration, TypeweaverPlugin } from \"./types\";\n\nexport type PluginRegistryApi = {\n readonly register: (plugin: TypeweaverPlugin, config?: unknown) => void;\n readonly get: (name: string) => PluginRegistration | undefined;\n readonly getAll: () => PluginRegistration[];\n readonly has: (name: string) => boolean;\n readonly clear: () => void;\n};\n\nexport function createPluginRegistry(): PluginRegistryApi {\n const plugins = new Map<string, PluginRegistration>();\n\n return {\n register: (plugin: TypeweaverPlugin, config?: unknown): void => {\n if (plugins.has(plugin.name)) {\n console.info(\n `Skipping duplicate registration of required plugin: ${plugin.name}`\n );\n return;\n }\n\n const registration: PluginRegistration = {\n name: plugin.name,\n plugin,\n config: config as Record<string, unknown>,\n };\n\n plugins.set(plugin.name, registration);\n console.info(`Registered plugin: ${plugin.name}`);\n },\n get: (name: string) => plugins.get(name),\n getAll: () => Array.from(plugins.values()),\n has: (name: string) => plugins.has(name),\n clear: () => plugins.clear(),\n };\n}\n","import path from \"node:path\";\n\nexport function relative(from: string, to: string): string {\n const relativePath = path.relative(from, to);\n\n if (relativePath.includes(\"node_modules\")) {\n const parts = relativePath.split(path.sep);\n const index = parts.indexOf(\"node_modules\");\n return parts.slice(index + 1).join(\"/\");\n }\n\n const posixPath = relativePath.split(path.sep).join(\"/\");\n\n if (!posixPath.startsWith(\"./\") && !posixPath.startsWith(\"../\")) {\n return `./${posixPath}`;\n }\n\n return posixPath;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport ejs from \"ejs\";\nimport { relative } from \"../helpers/path\";\nimport type { NormalizedResponse, NormalizedSpec } from \"../NormalizedSpec\";\nimport type { GeneratorContext, PluginConfig, PluginContext } from \"./types\";\n\nexport type PluginContextBuilderApi = {\n readonly createPluginContext: (params: {\n outputDir: string;\n inputDir: string;\n config: PluginConfig;\n }) => PluginContext;\n readonly createGeneratorContext: (params: {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n }) => GeneratorContext;\n readonly getGeneratedFiles: () => string[];\n readonly clearGeneratedFiles: () => void;\n};\n\nexport function createPluginContextBuilder(): PluginContextBuilderApi {\n const generatedFiles = new Set<string>();\n\n const createPluginContext = (params: {\n outputDir: string;\n inputDir: string;\n config: PluginConfig;\n }): PluginContext => {\n return {\n outputDir: params.outputDir,\n inputDir: params.inputDir,\n config: params.config,\n };\n };\n\n const createGeneratorContext = (params: {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n }): GeneratorContext => {\n const pluginContext = createPluginContext(params);\n const canonicalResponsesByName = new Map<string, NormalizedResponse>(\n params.normalizedSpec.responses.map(response => [response.name, response])\n );\n\n const getResourceOutputDir = (resourceName: string): string => {\n return path.join(params.outputDir, resourceName);\n };\n\n const getOperationOutputPaths = (config: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => {\n const outputDir = getResourceOutputDir(config.resourceName);\n const requestFileName = `${config.operationId}Request.ts`;\n const responseFileName = `${config.operationId}Response.ts`;\n const requestValidationFileName = `${config.operationId}RequestValidator.ts`;\n const responseValidationFileName = `${config.operationId}ResponseValidator.ts`;\n const clientFileName = `${config.operationId}Client.ts`;\n\n return {\n outputDir,\n requestFile: path.join(outputDir, requestFileName),\n requestFileName,\n responseFile: path.join(outputDir, responseFileName),\n responseFileName,\n requestValidationFile: path.join(outputDir, requestValidationFileName),\n requestValidationFileName,\n responseValidationFile: path.join(\n outputDir,\n responseValidationFileName\n ),\n responseValidationFileName,\n clientFile: path.join(outputDir, clientFileName),\n clientFileName,\n };\n };\n\n const getCanonicalResponse = (responseName: string): NormalizedResponse => {\n const response = canonicalResponsesByName.get(responseName);\n\n if (response === undefined) {\n throw new Error(`Missing canonical response '${responseName}'.`);\n }\n\n return response;\n };\n\n const getCanonicalResponseOutputFile = (responseName: string): string => {\n return path.join(params.responsesOutputDir, `${responseName}Response.ts`);\n };\n\n return {\n ...pluginContext,\n normalizedSpec: params.normalizedSpec,\n templateDir: params.templateDir,\n coreDir: params.coreDir,\n responsesOutputDir: params.responsesOutputDir,\n specOutputDir: params.specOutputDir,\n getCanonicalResponse,\n getCanonicalResponseOutputFile,\n getCanonicalResponseImportPath: config => {\n return relative(\n config.importerDir,\n getCanonicalResponseOutputFile(config.responseName).replace(\n /\\.ts$/,\n \"\"\n )\n );\n },\n getSpecImportPath: config => {\n return relative(\n config.importerDir,\n path.join(params.specOutputDir, \"spec\").replace(/\\.ts$/, \"\")\n );\n },\n getOperationDefinitionAccessor: config => {\n return (\n `getOperationDefinition(` +\n `spec, ` +\n `${JSON.stringify(config.resourceName)}, ` +\n `${JSON.stringify(config.operationId)}` +\n `)`\n );\n },\n getOperationOutputPaths,\n getResourceOutputDir,\n\n writeFile: (relativePath: string, content: string) => {\n const fullPath = path.join(params.outputDir, relativePath);\n const dir = path.dirname(fullPath);\n\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(fullPath, content);\n generatedFiles.add(relativePath);\n\n console.info(`Generated: ${relativePath}`);\n },\n\n renderTemplate: (templatePath: string, data: unknown) => {\n const fullTemplatePath = path.isAbsolute(templatePath)\n ? templatePath\n : path.join(params.templateDir, templatePath);\n\n const template = fs.readFileSync(fullTemplatePath, \"utf8\");\n return ejs.render(template, data as ejs.Data);\n },\n\n addGeneratedFile: (relativePath: string) => {\n generatedFiles.add(relativePath);\n },\n\n getGeneratedFiles: () => {\n return Array.from(generatedFiles);\n },\n };\n };\n\n return {\n createPluginContext,\n createGeneratorContext,\n getGeneratedFiles: () => Array.from(generatedFiles),\n clearGeneratedFiles: () => generatedFiles.clear(),\n };\n}\n","import { HttpMethod } from \"@rexeus/typeweaver-core\";\n\n/**\n * HTTP method priority for route ordering.\n * Lower numbers = higher priority (sorted first).\n */\nconst METHOD_PRIORITY: Record<string, number> = {\n [HttpMethod.GET]: 1,\n [HttpMethod.POST]: 2,\n [HttpMethod.PUT]: 3,\n [HttpMethod.PATCH]: 4,\n [HttpMethod.DELETE]: 5,\n [HttpMethod.OPTIONS]: 6,\n [HttpMethod.HEAD]: 7,\n};\n\n/**\n * Returns the sort priority for an HTTP method.\n * Unrecognized methods default to priority 999.\n */\nexport const getMethodPriority = (method: string): number =>\n METHOD_PRIORITY[method] ?? 999;\n\n/**\n * Compares two path segments for route ordering.\n * Returns negative if a should come before b, positive if after.\n *\n * Order: static segments before parameters, then alphabetically.\n */\nconst comparePathSegments = (a: string, b: string): number => {\n const aIsParam = a.startsWith(\":\");\n const bIsParam = b.startsWith(\":\");\n\n if (aIsParam !== bIsParam) {\n return aIsParam ? 1 : -1;\n }\n\n return a.localeCompare(b);\n};\n\n/**\n * Compares two routes for ordering.\n * Routes are sorted by:\n * 1. Path depth (shallow to deep)\n * 2. Static segments before parameters\n * 3. Alphabetical within same segment type\n * 4. HTTP method priority\n */\nexport const compareRoutes = (\n a: { method: string; path: string },\n b: { method: string; path: string }\n): number => {\n const aSegments = a.path.split(\"/\").filter(Boolean);\n const bSegments = b.path.split(\"/\").filter(Boolean);\n\n if (aSegments.length !== bSegments.length) {\n return aSegments.length - bSegments.length;\n }\n\n for (let i = 0; i < aSegments.length; i++) {\n const cmp = comparePathSegments(aSegments[i]!, bSegments[i]!);\n if (cmp !== 0) {\n return cmp;\n }\n }\n\n return getMethodPriority(a.method) - getMethodPriority(b.method);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidOperationIdError.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/InvalidResourceNameError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/helpers/namingUtils.ts","../src/helpers/routePath.ts","../src/validation/derivedResponseValidation.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/helpers/path.ts","../src/helpers/templateEngine.ts","../src/plugins/pluginContext.ts","../src/helpers/caseUtils.ts","../src/helpers/routeSort.ts"],"sourcesContent":["export class DerivedResponseCycleError extends Error {\n public constructor(responseName: string) {\n super(`Derived response '${responseName}' contains a cyclic lineage.`);\n this.name = \"DerivedResponseCycleError\";\n }\n}\n","export class DuplicateOperationIdError extends Error {\n public constructor(operationId: string) {\n super(\n `Operation ID '${operationId}' must be globally unique within a spec.`\n );\n this.name = \"DuplicateOperationIdError\";\n }\n}\n","export class DuplicateRouteError extends Error {\n public constructor(method: string, path: string, normalizedPath: string) {\n super(\n `Route '${method} ${path}' conflicts with an existing route using normalized path '${normalizedPath}'.`\n );\n this.name = \"DuplicateRouteError\";\n }\n}\n","export class EmptyOperationResponsesError extends Error {\n public constructor(operationId: string) {\n super(`Operation '${operationId}' must declare at least one response.`);\n this.name = \"EmptyOperationResponsesError\";\n }\n}\n","export class EmptyResourceOperationsError extends Error {\n public constructor(resourceName: string) {\n super(`Resource '${resourceName}' must contain at least one operation.`);\n this.name = \"EmptyResourceOperationsError\";\n }\n}\n","export class EmptySpecResourcesError extends Error {\n public constructor() {\n super(\"Spec definition must contain at least one resource.\");\n this.name = \"EmptySpecResourcesError\";\n }\n}\n","export class InvalidDerivedResponseError extends Error {\n public constructor(responseName: string) {\n super(\n `Derived response '${responseName}' contains invalid lineage metadata.`\n );\n this.name = \"InvalidDerivedResponseError\";\n }\n}\n","export class InvalidOperationIdError extends Error {\n public constructor(operationId: string) {\n super(\n `Operation ID '${operationId}' is invalid. Use camelCase (preferred) or PascalCase. snake_case and kebab-case are not supported.`\n );\n this.name = \"InvalidOperationIdError\";\n }\n}\n","import type { NormalizedRequest } from \"../NormalizedSpec\";\n\nexport class InvalidRequestSchemaError extends Error {\n public constructor(\n operationId: string,\n requestPart: keyof NormalizedRequest\n ) {\n super(\n `Operation '${operationId}' has an invalid request.${requestPart} schema definition.`\n );\n this.name = \"InvalidRequestSchemaError\";\n }\n}\n","export class InvalidResourceNameError extends Error {\n public constructor(resourceName: string) {\n super(\n `Resource name '${resourceName}' is invalid. Use camelCase singular nouns when possible; PascalCase is also supported. snake_case and kebab-case are not supported.`\n );\n this.name = \"InvalidResourceNameError\";\n }\n}\n","export class MissingDerivedResponseParentError extends Error {\n public constructor(responseName: string, parentName: string) {\n super(\n `Derived response '${responseName}' references missing canonical parent '${parentName}'.`\n );\n this.name = \"MissingDerivedResponseParentError\";\n }\n}\n","export class PathParameterMismatchError extends Error {\n public constructor(\n operationId: string,\n path: string,\n pathParams: readonly string[],\n requestParams: readonly string[]\n ) {\n super(\n `Operation '${operationId}' has mismatched path parameters for '${path}'. Path params: [${pathParams.join(\n \", \"\n )}], request.param keys: [${requestParams.join(\", \")}].`\n );\n this.name = \"PathParameterMismatchError\";\n }\n}\n","const CAMEL_CASE_PATTERN = /^[a-z][A-Za-z0-9]*$/;\nconst PASCAL_CASE_PATTERN = /^[A-Z][A-Za-z0-9]*$/;\n\nexport const isCamelCase = (value: string): boolean => {\n return CAMEL_CASE_PATTERN.test(value);\n};\n\nexport const isPascalCase = (value: string): boolean => {\n return PASCAL_CASE_PATTERN.test(value);\n};\n\nconst isSupportedIdentifierName = (value: string): boolean => {\n return isCamelCase(value) || isPascalCase(value);\n};\n\nexport const isSupportedOperationId = (value: string): boolean => {\n return isSupportedIdentifierName(value);\n};\n\nexport const isSupportedResourceName = (value: string): boolean => {\n return isSupportedIdentifierName(value);\n};\n","const PATH_PARAMETER_PATTERN = /:([A-Za-z0-9_]+)/g;\n\nexport const normalizeRoutePath = (path: string): string => {\n const segments = path.split(\"/\").filter(Boolean);\n\n if (segments.length === 0) {\n return \"/\";\n }\n\n return `/${segments.map(segment => (segment.startsWith(\":\") ? \":\" : segment)).join(\"/\")}`;\n};\n\nexport const getPathParameterNames = (path: string): string[] => {\n return Array.from(\n path.matchAll(PATH_PARAMETER_PATTERN),\n match => match[1] as string\n );\n};\n","import {\n HttpStatusCodeNameMap,\n isNamedResponseDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport type {\n ResponseDefinition,\n SpecDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport {\n DerivedResponseCycleError,\n InvalidDerivedResponseError,\n MissingDerivedResponseParentError,\n} from \"../errors\";\nimport type { NormalizedResponse } from \"../NormalizedSpec\";\n\nexport const validateDerivedResponseMetadata = (\n response: ResponseDefinition\n): void => {\n const derived = response.derived;\n\n if (derived === undefined) {\n return;\n }\n\n if (derived.parentName === response.name) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n if (derived.lineage.length === 0) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (derived.lineage.at(-1) !== response.name) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (derived.lineage.length !== derived.depth) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (new Set(derived.lineage).size !== derived.lineage.length) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n if (derived.depth > 1 && derived.lineage.at(-2) !== derived.parentName) {\n throw new InvalidDerivedResponseError(response.name);\n }\n};\n\nexport const collectCanonicalResponseDefinitions = (\n definition: SpecDefinition\n): Map<string, ResponseDefinition> => {\n const canonicalResponses = new Map<string, ResponseDefinition>();\n\n for (const resource of Object.values(definition.resources)) {\n for (const operation of resource.operations) {\n for (const response of operation.responses) {\n if (!isNamedResponseDefinition(response)) {\n continue;\n }\n\n validateDerivedResponseMetadata(response);\n\n canonicalResponses.set(response.name, response);\n }\n }\n }\n\n return canonicalResponses;\n};\n\nexport const getDerivedResponseChain = (\n response: ResponseDefinition,\n canonicalResponses: ReadonlyMap<string, ResponseDefinition>\n): readonly string[] => {\n const chain: string[] = [response.name];\n const visitedResponseNames = new Set(chain);\n let parentName = response.derived?.parentName;\n\n while (parentName !== undefined) {\n if (visitedResponseNames.has(parentName)) {\n throw new DerivedResponseCycleError(response.name);\n }\n\n const parentResponse = canonicalResponses.get(parentName);\n\n if (parentResponse === undefined) {\n throw new MissingDerivedResponseParentError(response.name, parentName);\n }\n\n chain.unshift(parentResponse.name);\n visitedResponseNames.add(parentResponse.name);\n parentName = parentResponse.derived?.parentName;\n }\n\n return chain;\n};\n\nexport const validateDerivedResponseGraph = (\n canonicalResponses: ReadonlyMap<string, ResponseDefinition>\n): void => {\n for (const response of canonicalResponses.values()) {\n if (response.derived === undefined) {\n continue;\n }\n\n const chain = getDerivedResponseChain(response, canonicalResponses);\n const materializedLineage = chain.slice(1);\n\n if (response.derived.depth !== materializedLineage.length) {\n throw new InvalidDerivedResponseError(response.name);\n }\n\n if (\n materializedLineage.length !== response.derived.lineage.length ||\n materializedLineage.some(\n (lineageEntry, index) =>\n lineageEntry !== response.derived?.lineage[index]\n )\n ) {\n throw new InvalidDerivedResponseError(response.name);\n }\n }\n};\n\nexport const normalizeResponseDefinition = (\n response: ResponseDefinition\n): NormalizedResponse => {\n return {\n name: response.name,\n statusCode: response.statusCode,\n statusCodeName: HttpStatusCodeNameMap[response.statusCode],\n description: response.description,\n header: response.header,\n body: response.body,\n kind: response.derived === undefined ? \"response\" : \"derived-response\",\n derivedFrom: response.derived?.parentName,\n lineage: response.derived?.lineage,\n depth: response.derived?.depth,\n };\n};\n\nexport const collectCanonicalResponses = (\n definition: SpecDefinition\n): Map<string, NormalizedResponse> => {\n const canonicalResponseDefinitions =\n collectCanonicalResponseDefinitions(definition);\n\n validateDerivedResponseGraph(canonicalResponseDefinitions);\n\n return new Map(\n Array.from(\n canonicalResponseDefinitions.entries(),\n ([responseName, response]) => [\n responseName,\n normalizeResponseDefinition(response),\n ]\n )\n );\n};\n","import {\n isNamedResponseDefinition,\n validateUniqueResponseNames,\n} from \"@rexeus/typeweaver-core\";\nimport type {\n RequestDefinition,\n ResourceDefinition,\n ResponseDefinition,\n SpecDefinition,\n} from \"@rexeus/typeweaver-core\";\nimport { z } from \"zod\";\nimport {\n DuplicateOperationIdError,\n DuplicateRouteError,\n EmptyOperationResponsesError,\n EmptyResourceOperationsError,\n EmptySpecResourcesError,\n InvalidOperationIdError,\n InvalidRequestSchemaError,\n InvalidResourceNameError,\n PathParameterMismatchError,\n} from \"./errors\";\nimport {\n isSupportedOperationId,\n isSupportedResourceName,\n} from \"./helpers/namingUtils\";\nimport { getPathParameterNames, normalizeRoutePath } from \"./helpers/routePath\";\nimport {\n collectCanonicalResponses,\n normalizeResponseDefinition,\n} from \"./validation\";\nimport type {\n NormalizedOperation,\n NormalizedRequest,\n NormalizedResponseUsage,\n NormalizedSpec,\n} from \"./NormalizedSpec\";\n\nconst isZodType = (schema: unknown): schema is z.ZodType => {\n return schema instanceof z.ZodType;\n};\n\nconst isZodObject = (\n schema: unknown\n): schema is z.ZodObject<z.core.$ZodShape> => {\n return schema instanceof z.ZodObject;\n};\n\nconst validateRequestSchema = (\n operationId: string,\n requestPart: keyof NormalizedRequest,\n schema: unknown\n): void => {\n if (!isZodType(schema)) {\n throw new InvalidRequestSchemaError(operationId, requestPart);\n }\n\n if (requestPart === \"param\" && !isZodObject(schema)) {\n throw new InvalidRequestSchemaError(operationId, requestPart);\n }\n};\n\nconst validateRequest = (\n operationId: string,\n path: string,\n request: RequestDefinition\n): NormalizedRequest | undefined => {\n if (request.header !== undefined) {\n validateRequestSchema(operationId, \"header\", request.header);\n }\n\n if (request.param !== undefined) {\n validateRequestSchema(operationId, \"param\", request.param);\n }\n\n if (request.query !== undefined) {\n validateRequestSchema(operationId, \"query\", request.query);\n }\n\n if (request.body !== undefined) {\n validateRequestSchema(operationId, \"body\", request.body);\n }\n\n const pathParams = getPathParameterNames(path);\n const requestParams =\n request.param === undefined ? [] : Object.keys(request.param.shape);\n\n if (\n pathParams.length !== requestParams.length ||\n pathParams.some(pathParam => !requestParams.includes(pathParam))\n ) {\n throw new PathParameterMismatchError(\n operationId,\n path,\n pathParams,\n requestParams\n );\n }\n\n if (\n request.header === undefined &&\n request.param === undefined &&\n request.query === undefined &&\n request.body === undefined\n ) {\n return undefined;\n }\n\n return {\n header: request.header,\n param: request.param,\n query: request.query,\n body: request.body,\n };\n};\n\nconst normalizeOperationResponses = (\n responses: readonly ResponseDefinition[]\n): NormalizedResponseUsage[] => {\n return responses.map(response => {\n if (isNamedResponseDefinition(response)) {\n return {\n responseName: response.name,\n source: \"canonical\",\n };\n }\n\n return {\n responseName: response.name,\n source: \"inline\",\n response: normalizeResponseDefinition(response),\n };\n });\n};\n\nconst normalizeOperation = (\n operationIds: Set<string>,\n routeKeys: Set<string>,\n operation: ResourceDefinition[\"operations\"][number]\n): NormalizedOperation => {\n if (!isSupportedOperationId(operation.operationId)) {\n throw new InvalidOperationIdError(operation.operationId);\n }\n\n if (operationIds.has(operation.operationId)) {\n throw new DuplicateOperationIdError(operation.operationId);\n }\n\n operationIds.add(operation.operationId);\n\n const normalizedPath = normalizeRoutePath(operation.path);\n const routeKey = `${operation.method}:${normalizedPath}`;\n\n if (routeKeys.has(routeKey)) {\n throw new DuplicateRouteError(\n operation.method,\n operation.path,\n normalizedPath\n );\n }\n\n routeKeys.add(routeKey);\n\n if (operation.responses.length === 0) {\n throw new EmptyOperationResponsesError(operation.operationId);\n }\n\n return {\n operationId: operation.operationId,\n method: operation.method,\n path: operation.path,\n summary: operation.summary,\n request: validateRequest(\n operation.operationId,\n operation.path,\n operation.request\n ),\n responses: normalizeOperationResponses(operation.responses),\n };\n};\n\nexport const normalizeSpec = (definition: SpecDefinition): NormalizedSpec => {\n const resourceEntries = Object.entries(definition.resources);\n\n if (resourceEntries.length === 0) {\n throw new EmptySpecResourcesError();\n }\n\n validateUniqueResponseNames(definition.resources);\n const canonicalResponses = collectCanonicalResponses(definition);\n const operationIds = new Set<string>();\n const routeKeys = new Set<string>();\n\n return {\n resources: resourceEntries.map(([resourceName, resource]) => {\n if (!isSupportedResourceName(resourceName)) {\n throw new InvalidResourceNameError(resourceName);\n }\n\n if (resource.operations.length === 0) {\n throw new EmptyResourceOperationsError(resourceName);\n }\n\n return {\n name: resourceName,\n operations: resource.operations.map(operation =>\n normalizeOperation(operationIds, routeKeys, operation)\n ),\n };\n }),\n responses: Array.from(canonicalResponses.values()),\n };\n};\n","import type { NormalizedResponse, NormalizedSpec } from \"../NormalizedSpec\";\n\n/**\n * Configuration for a typeweaver plugin\n */\nexport type PluginConfig = Record<string, unknown>;\n\n/**\n * Context provided to plugins during initialization and finalization\n */\nexport type PluginContext = {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n};\n\nexport type OperationOutputPaths = {\n readonly outputDir: string;\n readonly requestFile: string;\n readonly requestFileName: string;\n readonly responseFile: string;\n readonly responseFileName: string;\n readonly requestValidationFile: string;\n readonly requestValidationFileName: string;\n readonly responseValidationFile: string;\n readonly responseValidationFileName: string;\n readonly clientFile: string;\n readonly clientFileName: string;\n};\n\n/**\n * Context provided to plugins during generation\n */\nexport type GeneratorContext = PluginContext & {\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n\n readonly getCanonicalResponse: (responseName: string) => NormalizedResponse;\n readonly getCanonicalResponseOutputFile: (responseName: string) => string;\n readonly getCanonicalResponseImportPath: (params: {\n readonly importerDir: string;\n readonly responseName: string;\n }) => string;\n readonly getSpecImportPath: (params: {\n readonly importerDir: string;\n }) => string;\n readonly getOperationDefinitionAccessor: (params: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => string;\n readonly getOperationOutputPaths: (params: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => OperationOutputPaths;\n readonly getResourceOutputDir: (resourceName: string) => string;\n readonly writeFile: (relativePath: string, content: string) => void;\n readonly renderTemplate: (templatePath: string, data: unknown) => string;\n readonly addGeneratedFile: (relativePath: string) => void;\n readonly getGeneratedFiles: () => string[];\n};\n\n/**\n * Plugin metadata\n */\nexport type PluginMetadata = {\n readonly name: string;\n};\n\n/**\n * typeweaver plugin interface\n */\nexport type TypeweaverPlugin = PluginMetadata & {\n /**\n * Initialize the plugin\n * Called before any generation happens\n */\n initialize?(context: PluginContext): Promise<void> | void;\n\n /**\n * Collect and transform resources\n * Allows plugins to modify the resource collection\n */\n collectResources?(\n normalizedSpec: NormalizedSpec\n ): Promise<NormalizedSpec> | NormalizedSpec;\n\n /**\n * Main generation logic\n * Called with all resources and utilities\n */\n generate?(context: GeneratorContext): Promise<void> | void;\n\n /**\n * Finalize the plugin\n * Called after all generation is complete\n */\n finalize?(context: PluginContext): Promise<void> | void;\n};\n\n/**\n * Plugin constructor type\n */\nexport type PluginConstructor = new (config?: PluginConfig) => TypeweaverPlugin;\n\n/**\n * Plugin module export\n */\nexport type PluginModule = {\n default: PluginConstructor;\n};\n\n/**\n * Plugin registration entry\n */\nexport type PluginRegistration = {\n name: string;\n plugin: TypeweaverPlugin;\n config?: PluginConfig;\n};\n\n/**\n * typeweaver configuration\n */\nexport type TypeweaverConfig = {\n input: string;\n output: string;\n plugins?: (string | [string, PluginConfig])[];\n format?: boolean;\n clean?: boolean;\n};\n\n/**\n * Plugin loading error\n */\nexport class PluginLoadError extends Error {\n constructor(\n public pluginName: string,\n message: string\n ) {\n super(`Failed to load plugin '${pluginName}': ${message}`);\n this.name = \"PluginLoadError\";\n }\n}\n\n/**\n * Plugin dependency error\n */\nexport class PluginDependencyError extends Error {\n constructor(\n public pluginName: string,\n public missingDependency: string\n ) {\n super(\n `Plugin '${pluginName}' depends on '${missingDependency}' which is not loaded`\n );\n this.name = \"PluginDependencyError\";\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { NormalizedSpec } from \"../NormalizedSpec\";\nimport type {\n GeneratorContext,\n PluginConfig,\n PluginContext,\n TypeweaverPlugin,\n} from \"./types\";\n\n/**\n * Base class for typeweaver plugins\n * Provides default implementations and common utilities\n */\nexport abstract class BasePlugin implements TypeweaverPlugin {\n abstract name: string;\n description?: string;\n author?: string;\n depends?: string[];\n\n protected config: PluginConfig;\n\n constructor(config: PluginConfig = {}) {\n this.config = config;\n }\n\n /**\n * Default implementation - override in subclasses if needed\n */\n async initialize(_context: PluginContext): Promise<void> {\n // Default: no initialization needed\n }\n\n /**\n * Default implementation - override in subclasses if needed\n */\n collectResources(normalizedSpec: NormalizedSpec): NormalizedSpec {\n return normalizedSpec;\n }\n\n /**\n * Main generation logic - must be implemented by subclasses\n */\n abstract generate(context: GeneratorContext): Promise<void> | void;\n\n /**\n * Default implementation - override in subclasses if needed\n */\n async finalize(_context: PluginContext): Promise<void> {\n // Default: no finalization needed\n }\n\n protected copyLibFiles(\n context: GeneratorContext,\n libSourceDir: string,\n libNamespace: string\n ): void {\n if (!fs.existsSync(libSourceDir)) return;\n\n const libDir = path.join(context.outputDir, \"lib\", libNamespace);\n\n fs.cpSync(libSourceDir, libDir, { recursive: true });\n\n const libIndexPath = path.join(\"lib\", libNamespace, \"index.ts\");\n if (fs.existsSync(path.join(libDir, \"index.ts\"))) {\n context.addGeneratedFile(libIndexPath);\n }\n }\n}\n","import type { PluginRegistration, TypeweaverPlugin } from \"./types\";\n\nexport type PluginRegistryApi = {\n readonly register: (plugin: TypeweaverPlugin, config?: unknown) => void;\n readonly get: (name: string) => PluginRegistration | undefined;\n readonly getAll: () => PluginRegistration[];\n readonly has: (name: string) => boolean;\n readonly clear: () => void;\n};\n\nexport function createPluginRegistry(): PluginRegistryApi {\n const plugins = new Map<string, PluginRegistration>();\n\n return {\n register: (plugin: TypeweaverPlugin, config?: unknown): void => {\n if (plugins.has(plugin.name)) {\n console.info(\n `Skipping duplicate registration of required plugin: ${plugin.name}`\n );\n return;\n }\n\n const registration: PluginRegistration = {\n name: plugin.name,\n plugin,\n config: config as Record<string, unknown>,\n };\n\n plugins.set(plugin.name, registration);\n console.info(`Registered plugin: ${plugin.name}`);\n },\n get: (name: string) => plugins.get(name),\n getAll: () => Array.from(plugins.values()),\n has: (name: string) => plugins.has(name),\n clear: () => plugins.clear(),\n };\n}\n","import path from \"node:path\";\n\nexport function relative(from: string, to: string): string {\n const relativePath = path.relative(from, to);\n\n if (relativePath.includes(\"node_modules\")) {\n const parts = relativePath.split(path.sep);\n const index = parts.indexOf(\"node_modules\");\n return parts.slice(index + 1).join(\"/\");\n }\n\n const posixPath = relativePath.split(path.sep).join(\"/\");\n\n if (!posixPath.startsWith(\"./\") && !posixPath.startsWith(\"../\")) {\n return `./${posixPath}`;\n }\n\n return posixPath;\n}\n","function escapeHtml(input: string): string {\n return input\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n\nfunction stringifyTemplateValue(value: unknown): string {\n if (value === undefined || value === null) {\n return \"\";\n }\n\n return String(value);\n}\n\nexport function renderTemplate(\n template: string,\n data: Record<string, unknown>\n): string {\n const outputChunks: string[] = [];\n const expressionPattern = /<%[=-]?[\\s\\S]*?%>/g;\n let currentIndex = 0;\n let match: RegExpExecArray | null = expressionPattern.exec(template);\n\n while (match !== null) {\n const [tag] = match;\n const tagStart = match.index;\n\n outputChunks.push(\n `__output.push(${JSON.stringify(template.slice(currentIndex, tagStart))});`\n );\n\n if (tag.startsWith(\"<%=\")) {\n const expression = tag.slice(3, -2).trim();\n outputChunks.push(`__output.push(__escape(__stringify(${expression})));`);\n } else if (tag.startsWith(\"<%-\")) {\n const expression = tag.slice(3, -2).trim();\n outputChunks.push(`__output.push(__stringify(${expression}));`);\n } else {\n outputChunks.push(tag.slice(2, -2));\n }\n\n currentIndex = tagStart + tag.length;\n match = expressionPattern.exec(template);\n }\n\n outputChunks.push(\n `__output.push(${JSON.stringify(template.slice(currentIndex))});`\n );\n\n const render = new Function(\n \"data\",\n \"__escape\",\n \"__stringify\",\n // This intentionally relies on `new Function()` sloppy mode so `with (data)`\n // can expose template variables as bare identifiers during rendering.\n `const __output = []; with (data) { ${outputChunks.join(\"\\n\")} } return __output.join(\"\");`\n ) as (\n data: Record<string, unknown>,\n escape: typeof escapeHtml,\n stringify: typeof stringifyTemplateValue\n ) => string;\n\n return render(data, escapeHtml, stringifyTemplateValue);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { relative } from \"../helpers/path\";\nimport { renderTemplate } from \"../helpers/templateEngine\";\nimport type { NormalizedResponse, NormalizedSpec } from \"../NormalizedSpec\";\nimport type { GeneratorContext, PluginConfig, PluginContext } from \"./types\";\n\nexport type PluginContextBuilderApi = {\n readonly createPluginContext: (params: {\n outputDir: string;\n inputDir: string;\n config: PluginConfig;\n }) => PluginContext;\n readonly createGeneratorContext: (params: {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n }) => GeneratorContext;\n readonly getGeneratedFiles: () => string[];\n readonly clearGeneratedFiles: () => void;\n};\n\nexport function createPluginContextBuilder(): PluginContextBuilderApi {\n const generatedFiles = new Set<string>();\n\n const createPluginContext = (params: {\n outputDir: string;\n inputDir: string;\n config: PluginConfig;\n }): PluginContext => {\n return {\n outputDir: params.outputDir,\n inputDir: params.inputDir,\n config: params.config,\n };\n };\n\n const createGeneratorContext = (params: {\n readonly outputDir: string;\n readonly inputDir: string;\n readonly config: PluginConfig;\n readonly normalizedSpec: NormalizedSpec;\n readonly templateDir: string;\n readonly coreDir: string;\n readonly responsesOutputDir: string;\n readonly specOutputDir: string;\n }): GeneratorContext => {\n const pluginContext = createPluginContext(params);\n const canonicalResponsesByName = new Map<string, NormalizedResponse>(\n params.normalizedSpec.responses.map(response => [response.name, response])\n );\n\n const getResourceOutputDir = (resourceName: string): string => {\n return path.join(params.outputDir, resourceName);\n };\n\n const getOperationOutputPaths = (config: {\n readonly resourceName: string;\n readonly operationId: string;\n }) => {\n const outputDir = getResourceOutputDir(config.resourceName);\n const requestFileName = `${config.operationId}Request.ts`;\n const responseFileName = `${config.operationId}Response.ts`;\n const requestValidationFileName = `${config.operationId}RequestValidator.ts`;\n const responseValidationFileName = `${config.operationId}ResponseValidator.ts`;\n const clientFileName = `${config.operationId}Client.ts`;\n\n return {\n outputDir,\n requestFile: path.join(outputDir, requestFileName),\n requestFileName,\n responseFile: path.join(outputDir, responseFileName),\n responseFileName,\n requestValidationFile: path.join(outputDir, requestValidationFileName),\n requestValidationFileName,\n responseValidationFile: path.join(\n outputDir,\n responseValidationFileName\n ),\n responseValidationFileName,\n clientFile: path.join(outputDir, clientFileName),\n clientFileName,\n };\n };\n\n const getCanonicalResponse = (responseName: string): NormalizedResponse => {\n const response = canonicalResponsesByName.get(responseName);\n\n if (response === undefined) {\n throw new Error(`Missing canonical response '${responseName}'.`);\n }\n\n return response;\n };\n\n const getCanonicalResponseOutputFile = (responseName: string): string => {\n return path.join(params.responsesOutputDir, `${responseName}Response.ts`);\n };\n\n return {\n ...pluginContext,\n normalizedSpec: params.normalizedSpec,\n templateDir: params.templateDir,\n coreDir: params.coreDir,\n responsesOutputDir: params.responsesOutputDir,\n specOutputDir: params.specOutputDir,\n getCanonicalResponse,\n getCanonicalResponseOutputFile,\n getCanonicalResponseImportPath: config => {\n return relative(\n config.importerDir,\n getCanonicalResponseOutputFile(config.responseName).replace(\n /\\.ts$/,\n \"\"\n )\n );\n },\n getSpecImportPath: config => {\n return relative(\n config.importerDir,\n path.join(params.specOutputDir, \"spec\").replace(/\\.ts$/, \"\")\n );\n },\n getOperationDefinitionAccessor: config => {\n return (\n `getOperationDefinition(` +\n `spec, ` +\n `${JSON.stringify(config.resourceName)}, ` +\n `${JSON.stringify(config.operationId)}` +\n `)`\n );\n },\n getOperationOutputPaths,\n getResourceOutputDir,\n\n writeFile: (relativePath: string, content: string) => {\n const fullPath = path.join(params.outputDir, relativePath);\n const dir = path.dirname(fullPath);\n\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(fullPath, content);\n generatedFiles.add(relativePath);\n\n console.info(`Generated: ${relativePath}`);\n },\n\n renderTemplate: (templatePath: string, data: unknown) => {\n const fullTemplatePath = path.isAbsolute(templatePath)\n ? templatePath\n : path.join(params.templateDir, templatePath);\n\n const template = fs.readFileSync(fullTemplatePath, \"utf8\");\n return renderTemplate(\n template,\n (data ?? {}) as Record<string, unknown>\n );\n },\n\n addGeneratedFile: (relativePath: string) => {\n generatedFiles.add(relativePath);\n },\n\n getGeneratedFiles: () => {\n return Array.from(generatedFiles);\n },\n };\n };\n\n return {\n createPluginContext,\n createGeneratorContext,\n getGeneratedFiles: () => Array.from(generatedFiles),\n clearGeneratedFiles: () => generatedFiles.clear(),\n };\n}\n","function splitWords(input: string): string[] {\n return input\n .trim()\n .replace(/[_\\-\\s]+/g, \" \")\n .replace(/([a-z\\d])([A-Z])/g, \"$1 $2\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n .split(\" \")\n .filter(Boolean)\n .map(word => word.toLowerCase());\n}\n\nfunction capitalize(word: string): string {\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\nexport function toPascalCase(input: string): string {\n return splitWords(input).map(capitalize).join(\"\");\n}\n\nexport function toCamelCase(input: string): string {\n const [firstWord = \"\", ...remainingWords] = splitWords(input);\n\n return firstWord + remainingWords.map(capitalize).join(\"\");\n}\n","import { HttpMethod } from \"@rexeus/typeweaver-core\";\n\n/**\n * HTTP method priority for route ordering.\n * Lower numbers = higher priority (sorted first).\n */\nconst METHOD_PRIORITY: Record<string, number> = {\n [HttpMethod.GET]: 1,\n [HttpMethod.POST]: 2,\n [HttpMethod.PUT]: 3,\n [HttpMethod.PATCH]: 4,\n [HttpMethod.DELETE]: 5,\n [HttpMethod.OPTIONS]: 6,\n [HttpMethod.HEAD]: 7,\n};\n\n/**\n * Returns the sort priority for an HTTP method.\n * Unrecognized methods default to priority 999.\n */\nexport const getMethodPriority = (method: string): number =>\n METHOD_PRIORITY[method] ?? 999;\n\n/**\n * Compares two path segments for route ordering.\n * Returns negative if a should come before b, positive if after.\n *\n * Order: static segments before parameters, then alphabetically.\n */\nconst comparePathSegments = (a: string, b: string): number => {\n const aIsParam = a.startsWith(\":\");\n const bIsParam = b.startsWith(\":\");\n\n if (aIsParam !== bIsParam) {\n return aIsParam ? 1 : -1;\n }\n\n return a.localeCompare(b);\n};\n\n/**\n * Compares two routes for ordering.\n * Routes are sorted by:\n * 1. Path depth (shallow to deep)\n * 2. Static segments before parameters\n * 3. Alphabetical within same segment type\n * 4. HTTP method priority\n */\nexport const compareRoutes = (\n a: { method: string; path: string },\n b: { method: string; path: string }\n): number => {\n const aSegments = a.path.split(\"/\").filter(Boolean);\n const bSegments = b.path.split(\"/\").filter(Boolean);\n\n if (aSegments.length !== bSegments.length) {\n return aSegments.length - bSegments.length;\n }\n\n for (let i = 0; i < aSegments.length; i++) {\n const cmp = comparePathSegments(aSegments[i]!, bSegments[i]!);\n if (cmp !== 0) {\n return cmp;\n }\n }\n\n return getMethodPriority(a.method) - getMethodPriority(b.method);\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexeus/typeweaver-gen",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Template-driven engine that turns structured API definitions into production-ready artifacts. Powered by Typeweaver 🧵✨",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -48,14 +48,11 @@
48
48
  "homepage": "https://github.com/rexeus/typeweaver#readme",
49
49
  "peerDependencies": {
50
50
  "zod": "^4.3.0",
51
- "@rexeus/typeweaver-core": "^0.9.2"
51
+ "@rexeus/typeweaver-core": "^0.10.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "zod": "^4.3.6",
55
- "@rexeus/typeweaver-core": "^0.9.2"
56
- },
57
- "dependencies": {
58
- "ejs": "^5.0.1"
55
+ "@rexeus/typeweaver-core": "^0.10.0"
59
56
  },
60
57
  "scripts": {
61
58
  "typecheck": "tsc --noEmit",