@medusajs/http-types-generator 2.13.6-preview-20260402101111

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.
Files changed (111) hide show
  1. package/README.md +135 -0
  2. package/dist/__tests__/compatibility-checker.spec.d.ts +2 -0
  3. package/dist/__tests__/compatibility-checker.spec.d.ts.map +1 -0
  4. package/dist/__tests__/compatibility-checker.spec.js +231 -0
  5. package/dist/__tests__/compatibility-checker.spec.js.map +1 -0
  6. package/dist/__tests__/config.spec.d.ts +2 -0
  7. package/dist/__tests__/config.spec.d.ts.map +1 -0
  8. package/dist/__tests__/config.spec.js +78 -0
  9. package/dist/__tests__/config.spec.js.map +1 -0
  10. package/dist/__tests__/import-tracker.spec.d.ts +2 -0
  11. package/dist/__tests__/import-tracker.spec.d.ts.map +1 -0
  12. package/dist/__tests__/import-tracker.spec.js +25 -0
  13. package/dist/__tests__/import-tracker.spec.js.map +1 -0
  14. package/dist/__tests__/name-classifier.spec.d.ts +2 -0
  15. package/dist/__tests__/name-classifier.spec.d.ts.map +1 -0
  16. package/dist/__tests__/name-classifier.spec.js +77 -0
  17. package/dist/__tests__/name-classifier.spec.js.map +1 -0
  18. package/dist/__tests__/name-registry.spec.d.ts +2 -0
  19. package/dist/__tests__/name-registry.spec.d.ts.map +1 -0
  20. package/dist/__tests__/name-registry.spec.js +67 -0
  21. package/dist/__tests__/name-registry.spec.js.map +1 -0
  22. package/dist/__tests__/path-mapper.spec.d.ts +2 -0
  23. package/dist/__tests__/path-mapper.spec.d.ts.map +1 -0
  24. package/dist/__tests__/path-mapper.spec.js +98 -0
  25. package/dist/__tests__/path-mapper.spec.js.map +1 -0
  26. package/dist/__tests__/type-emitter.spec.d.ts +2 -0
  27. package/dist/__tests__/type-emitter.spec.d.ts.map +1 -0
  28. package/dist/__tests__/type-emitter.spec.js +173 -0
  29. package/dist/__tests__/type-emitter.spec.js.map +1 -0
  30. package/dist/__tests__/type-pipeline.spec.d.ts +2 -0
  31. package/dist/__tests__/type-pipeline.spec.d.ts.map +1 -0
  32. package/dist/__tests__/type-pipeline.spec.js +239 -0
  33. package/dist/__tests__/type-pipeline.spec.js.map +1 -0
  34. package/dist/__tests__/utils/ts-utils.d.ts +22 -0
  35. package/dist/__tests__/utils/ts-utils.d.ts.map +1 -0
  36. package/dist/__tests__/utils/ts-utils.js +66 -0
  37. package/dist/__tests__/utils/ts-utils.js.map +1 -0
  38. package/dist/commands/generate.d.ts +10 -0
  39. package/dist/commands/generate.d.ts.map +1 -0
  40. package/dist/commands/generate.js +215 -0
  41. package/dist/commands/generate.js.map +1 -0
  42. package/dist/commands/validate.d.ts +14 -0
  43. package/dist/commands/validate.d.ts.map +1 -0
  44. package/dist/commands/validate.js +201 -0
  45. package/dist/commands/validate.js.map +1 -0
  46. package/dist/config/index.d.ts +52 -0
  47. package/dist/config/index.d.ts.map +1 -0
  48. package/dist/config/index.js +119 -0
  49. package/dist/config/index.js.map +1 -0
  50. package/dist/core/compatibility-checker.d.ts +92 -0
  51. package/dist/core/compatibility-checker.d.ts.map +1 -0
  52. package/dist/core/compatibility-checker.js +415 -0
  53. package/dist/core/compatibility-checker.js.map +1 -0
  54. package/dist/core/import-tracker.d.ts +11 -0
  55. package/dist/core/import-tracker.d.ts.map +1 -0
  56. package/dist/core/import-tracker.js +17 -0
  57. package/dist/core/import-tracker.js.map +1 -0
  58. package/dist/core/program-factory.d.ts +23 -0
  59. package/dist/core/program-factory.d.ts.map +1 -0
  60. package/dist/core/program-factory.js +80 -0
  61. package/dist/core/program-factory.js.map +1 -0
  62. package/dist/core/schema-extractor.d.ts +73 -0
  63. package/dist/core/schema-extractor.d.ts.map +1 -0
  64. package/dist/core/schema-extractor.js +205 -0
  65. package/dist/core/schema-extractor.js.map +1 -0
  66. package/dist/core/type-emitter.d.ts +73 -0
  67. package/dist/core/type-emitter.d.ts.map +1 -0
  68. package/dist/core/type-emitter.js +246 -0
  69. package/dist/core/type-emitter.js.map +1 -0
  70. package/dist/core/type-resolver.d.ts +64 -0
  71. package/dist/core/type-resolver.d.ts.map +1 -0
  72. package/dist/core/type-resolver.js +163 -0
  73. package/dist/core/type-resolver.js.map +1 -0
  74. package/dist/index.d.ts +3 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +20 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/mapping/name-classifier.d.ts +34 -0
  79. package/dist/mapping/name-classifier.d.ts.map +1 -0
  80. package/dist/mapping/name-classifier.js +72 -0
  81. package/dist/mapping/name-classifier.js.map +1 -0
  82. package/dist/mapping/name-registry.d.ts +54 -0
  83. package/dist/mapping/name-registry.d.ts.map +1 -0
  84. package/dist/mapping/name-registry.js +251 -0
  85. package/dist/mapping/name-registry.js.map +1 -0
  86. package/dist/mapping/path-mapper.d.ts +62 -0
  87. package/dist/mapping/path-mapper.d.ts.map +1 -0
  88. package/dist/mapping/path-mapper.js +116 -0
  89. package/dist/mapping/path-mapper.js.map +1 -0
  90. package/dist/tsconfig.tsbuildinfo +1 -0
  91. package/dist/utils/file-merger.d.ts +47 -0
  92. package/dist/utils/file-merger.d.ts.map +1 -0
  93. package/dist/utils/file-merger.js +164 -0
  94. package/dist/utils/file-merger.js.map +1 -0
  95. package/dist/utils/formatter.d.ts +12 -0
  96. package/dist/utils/formatter.d.ts.map +1 -0
  97. package/dist/utils/formatter.js +31 -0
  98. package/dist/utils/formatter.js.map +1 -0
  99. package/dist/utils/fs-helpers.d.ts +21 -0
  100. package/dist/utils/fs-helpers.d.ts.map +1 -0
  101. package/dist/utils/fs-helpers.js +42 -0
  102. package/dist/utils/fs-helpers.js.map +1 -0
  103. package/dist/utils/index-manager.d.ts +24 -0
  104. package/dist/utils/index-manager.d.ts.map +1 -0
  105. package/dist/utils/index-manager.js +95 -0
  106. package/dist/utils/index-manager.js.map +1 -0
  107. package/dist/utils/ts-helpers.d.ts +87 -0
  108. package/dist/utils/ts-helpers.d.ts.map +1 -0
  109. package/dist/utils/ts-helpers.js +216 -0
  110. package/dist/utils/ts-helpers.js.map +1 -0
  111. package/package.json +41 -0
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const name_registry_1 = require("../mapping/name-registry");
4
+ describe("NameRegistry.resolveHttpTypeName", () => {
5
+ describe("global registry lookups", () => {
6
+ it("maps known validator names to their HTTP type names", () => {
7
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetProductsParams")).toBe("AdminProductListParams");
8
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminCustomersParams")).toBe("AdminCustomerFilters");
9
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersParams")).toBe("AdminOrderFilters");
10
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("StoreGetProductsParams")).toBe("StoreProductListParams");
11
+ });
12
+ it("falls back to the export name when no mapping exists", () => {
13
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminCreateProduct")).toBe("AdminCreateProduct");
14
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("SomeUnknownName")).toBe("SomeUnknownName");
15
+ });
16
+ });
17
+ describe("domain-scoped overrides", () => {
18
+ it("returns the domain override when it exists, taking precedence over global", () => {
19
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersOrderParams", "exchange")).toBe("AdminOrderExchangeListParams");
20
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersParams", "exchange")).toBe("AdminExchangeListParams");
21
+ });
22
+ it("returns 'skip' for domain entries explicitly set to skip", () => {
23
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersOrderParams", "return")).toBe("skip");
24
+ });
25
+ it("falls back to global registry when no domain override exists for the name", () => {
26
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminCustomersParams", "exchange")).toBe("AdminCustomerFilters");
27
+ });
28
+ it("falls back to the export name when no domain or global mapping exists", () => {
29
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminCreateCustomProduct", "unknown-domain")).toBe("AdminCreateCustomProduct");
30
+ });
31
+ it("ignores domain when it is undefined", () => {
32
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersOrderParams")).toBe("AdminGetOrderParams");
33
+ });
34
+ });
35
+ describe("claim domain overrides", () => {
36
+ it("maps AdminGetOrdersOrderParams to AdminClaimActionsParams in claim domain", () => {
37
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersOrderParams", "claim")).toBe("AdminClaimActionsParams");
38
+ });
39
+ it("maps AdminGetOrdersParams to AdminClaimListParams in claim domain", () => {
40
+ expect(name_registry_1.NameRegistry.resolveHttpTypeName("AdminGetOrdersParams", "claim")).toBe("AdminClaimListParams");
41
+ });
42
+ });
43
+ });
44
+ describe("NameRegistry.resolveValidatorName", () => {
45
+ it("reverse-maps known HTTP type names back to validator names", () => {
46
+ expect(name_registry_1.NameRegistry.resolveValidatorName("AdminProductListParams")).toBe("AdminGetProductsParams");
47
+ expect(name_registry_1.NameRegistry.resolveValidatorName("AdminCustomerFilters")).toBe("AdminCustomersParams");
48
+ expect(name_registry_1.NameRegistry.resolveValidatorName("AdminOrderFilters")).toBe("AdminGetOrdersParams");
49
+ });
50
+ it("falls back to the HTTP type name when no reverse mapping exists", () => {
51
+ expect(name_registry_1.NameRegistry.resolveValidatorName("AdminCreateProduct")).toBe("AdminCreateProduct");
52
+ expect(name_registry_1.NameRegistry.resolveValidatorName("SomeUnknownType")).toBe("SomeUnknownType");
53
+ });
54
+ });
55
+ describe("registry consistency", () => {
56
+ it("has unique keys (no duplicate validator names)", () => {
57
+ const keys = Object.keys(name_registry_1.VALIDATOR_TO_HTTP_TYPE_NAME);
58
+ expect(new Set(keys).size).toBe(keys.length);
59
+ });
60
+ it("domain-scoped override domains are valid path-mapper domain names", () => {
61
+ const domains = Object.keys(name_registry_1.DOMAIN_SCOPED_OVERRIDES);
62
+ for (const domain of domains) {
63
+ expect(domain).not.toMatch(/ges$|ces$|ons$/);
64
+ }
65
+ });
66
+ });
67
+ //# sourceMappingURL=name-registry.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"name-registry.spec.js","sourceRoot":"","sources":["../../src/__tests__/name-registry.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=path-mapper.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-mapper.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/path-mapper.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const path_mapper_1 = require("../mapping/path-mapper");
8
+ describe("PathMapper.mapValidatorToHttpTypes", () => {
9
+ const toAdminPath = (entity) => `/repo/packages/medusa/src/api/admin/${entity}/validators.ts`;
10
+ const toStorePath = (entity) => `/repo/packages/medusa/src/api/store/${entity}/validators.ts`;
11
+ describe("area detection", () => {
12
+ it("sets area to 'admin' for admin validator paths", () => {
13
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toAdminPath("products"));
14
+ expect(result?.area).toBe("admin");
15
+ });
16
+ it("sets area to 'store' for store validator paths", () => {
17
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toStorePath("products"));
18
+ expect(result?.area).toBe("store");
19
+ });
20
+ it("returns undefined for paths that don't match the expected structure", () => {
21
+ expect(path_mapper_1.PathMapper.mapValidatorToHttpTypes("/some/random/path/validators.ts")).toBeUndefined();
22
+ expect(path_mapper_1.PathMapper.mapValidatorToHttpTypes("/packages/medusa/src/api/middleware.ts")).toBeUndefined();
23
+ expect(path_mapper_1.PathMapper.mapValidatorToHttpTypes("")).toBeUndefined();
24
+ });
25
+ });
26
+ describe("entity name overrides", () => {
27
+ const cases = [
28
+ ["products", "product"],
29
+ ["orders", "order"],
30
+ ["customers", "customer"],
31
+ ["api-keys", "api-key"],
32
+ ["draft-orders", "draft-order"],
33
+ ["exchanges", "exchange"],
34
+ ["fulfillment-sets", "fulfillment-set"],
35
+ ["fulfillments", "fulfillment"],
36
+ ["inventory-items", "inventory"],
37
+ ["invites", "invite"],
38
+ ["notifications", "notification"],
39
+ ["order-changes", "order"],
40
+ ["payments", "payment"],
41
+ ["payment-collections", "payment"],
42
+ ["price-lists", "price-list"],
43
+ ["product-categories", "product-category"],
44
+ ["product-tags", "product-tag"],
45
+ ["product-types", "product-type"],
46
+ ["product-variants", "product"],
47
+ ["regions", "region"],
48
+ ["returns", "return"],
49
+ ["sales-channels", "sales-channel"],
50
+ ["shipping-options", "shipping-option"],
51
+ ["users", "user"],
52
+ ["workflow-executions", "workflow-execution"],
53
+ ["uploads", "file"],
54
+ ];
55
+ it.each(cases)("maps route dir '%s' → domain '%s'", (routeDir, expectedDomain) => {
56
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toAdminPath(routeDir));
57
+ expect(result?.domain).toBe(expectedDomain);
58
+ });
59
+ it("singularizes the route dir name when no override exists", () => {
60
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toAdminPath("locales"));
61
+ expect(result?.domain).toBe("locale");
62
+ });
63
+ });
64
+ describe("output paths", () => {
65
+ it("puts payloads.ts and queries.ts inside the outputDir", () => {
66
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toAdminPath("products"));
67
+ expect(result.payloadsFile).toBe(path_1.default.join(result.outputDir, "payloads.ts"));
68
+ expect(result.queriesFile).toBe(path_1.default.join(result.outputDir, "queries.ts"));
69
+ });
70
+ it("outputDir contains the domain and area segments", () => {
71
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toAdminPath("orders"));
72
+ expect(result.outputDir).toMatch(/order[/\\]admin/);
73
+ });
74
+ it("store paths use 'store' area in outputDir", () => {
75
+ const result = path_mapper_1.PathMapper.mapValidatorToHttpTypes(toStorePath("products"));
76
+ expect(result.outputDir).toMatch(/product[/\\]store/);
77
+ });
78
+ });
79
+ });
80
+ describe("PathMapper.getValidatorGlobs", () => {
81
+ it("returns one glob for area 'admin'", () => {
82
+ const globs = path_mapper_1.PathMapper.getValidatorGlobs("admin");
83
+ expect(globs).toHaveLength(1);
84
+ expect(globs[0]).toMatch(/api\/admin\/\*\/validators\.ts$/);
85
+ });
86
+ it("returns one glob for area 'store'", () => {
87
+ const globs = path_mapper_1.PathMapper.getValidatorGlobs("store");
88
+ expect(globs).toHaveLength(1);
89
+ expect(globs[0]).toMatch(/api\/store\/\*\/validators\.ts$/);
90
+ });
91
+ it("returns two globs for area 'all'", () => {
92
+ const globs = path_mapper_1.PathMapper.getValidatorGlobs("all");
93
+ expect(globs).toHaveLength(2);
94
+ expect(globs.some((g) => g.includes("admin"))).toBe(true);
95
+ expect(globs.some((g) => g.includes("store"))).toBe(true);
96
+ });
97
+ });
98
+ //# sourceMappingURL=path-mapper.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-mapper.spec.js","sourceRoot":"","sources":["../../src/__tests__/path-mapper.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=type-emitter.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-emitter.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/type-emitter.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const type_emitter_1 = require("../core/type-emitter");
4
+ const import_tracker_1 = require("../core/import-tracker");
5
+ const ts_utils_1 = require("./utils/ts-utils");
6
+ function makeResolved(type, opts = {}) {
7
+ return {
8
+ type,
9
+ hasFindParams: false,
10
+ hasSelectParams: false,
11
+ hasBaseFilterable: false,
12
+ schemaName: "TestType",
13
+ ...opts,
14
+ };
15
+ }
16
+ // ---------------------------------------------------------------------------
17
+ // TypeEmitter.emitInterface
18
+ // ---------------------------------------------------------------------------
19
+ describe("TypeEmitter.emitInterface", () => {
20
+ describe("basic field emission", () => {
21
+ it("emits required fields with their types", () => {
22
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { name: string; age: number }`);
23
+ const emitter = new type_emitter_1.TypeEmitter(checker);
24
+ const tracker = new import_tracker_1.ImportTracker();
25
+ const output = emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
26
+ expect(output).toContain("export interface AdminCreate");
27
+ expect(output).toContain("name: string");
28
+ expect(output).toContain("age: number");
29
+ });
30
+ it("emits optional fields with the question-mark token", () => {
31
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { name: string; description?: string }`);
32
+ const emitter = new type_emitter_1.TypeEmitter(checker);
33
+ const tracker = new import_tracker_1.ImportTracker();
34
+ const output = emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
35
+ expect(output).toContain("description?: string");
36
+ });
37
+ it("emits nullable fields as T | null", () => {
38
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { title: string | null }`);
39
+ const emitter = new type_emitter_1.TypeEmitter(checker);
40
+ const tracker = new import_tracker_1.ImportTracker();
41
+ const output = emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
42
+ expect(output).toContain("title: string | null");
43
+ });
44
+ it("emits array fields", () => {
45
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { tags: string[] }`);
46
+ const emitter = new type_emitter_1.TypeEmitter(checker);
47
+ const tracker = new import_tracker_1.ImportTracker();
48
+ const output = emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
49
+ expect(output).toContain("tags: string[]");
50
+ });
51
+ it("emits an empty interface when the type has no properties", () => {
52
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape {}`);
53
+ const emitter = new type_emitter_1.TypeEmitter(checker);
54
+ const tracker = new import_tracker_1.ImportTracker();
55
+ const output = emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
56
+ expect(output).toContain("export interface AdminCreate");
57
+ expect(output).not.toContain(":");
58
+ });
59
+ });
60
+ describe("extends clauses", () => {
61
+ it("adds 'extends FindParams' when hasFindParams is true", () => {
62
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { q?: string }`);
63
+ const emitter = new type_emitter_1.TypeEmitter(checker);
64
+ const tracker = new import_tracker_1.ImportTracker();
65
+ const output = emitter.emitInterface("AdminListParams", makeResolved(getType("Shape"), { hasFindParams: true }), tracker);
66
+ expect(output).toContain("extends FindParams");
67
+ expect(tracker.needsFindParams).toBe(true);
68
+ });
69
+ it("adds 'extends BaseFilterable<T>' when hasBaseFilterable is true", () => {
70
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { q?: string }`);
71
+ const emitter = new type_emitter_1.TypeEmitter(checker);
72
+ const tracker = new import_tracker_1.ImportTracker();
73
+ const output = emitter.emitInterface("AdminFilters", makeResolved(getType("Shape"), { hasBaseFilterable: true }), tracker);
74
+ expect(output).toContain("extends BaseFilterable<AdminFilters>");
75
+ expect(tracker.needsBaseFilterable).toBe(true);
76
+ });
77
+ it("adds both 'extends FindParams, BaseFilterable<T>' when both flags are true", () => {
78
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { q?: string }`);
79
+ const emitter = new type_emitter_1.TypeEmitter(checker);
80
+ const tracker = new import_tracker_1.ImportTracker();
81
+ const output = emitter.emitInterface("AdminListFilters", makeResolved(getType("Shape"), {
82
+ hasFindParams: true,
83
+ hasBaseFilterable: true,
84
+ }), tracker);
85
+ expect(output).toContain("FindParams");
86
+ expect(output).toContain("BaseFilterable<AdminListFilters>");
87
+ });
88
+ });
89
+ describe("import tracker", () => {
90
+ it("does not set any tracker flags for a plain interface", () => {
91
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape { name: string }`);
92
+ const emitter = new type_emitter_1.TypeEmitter(checker);
93
+ const tracker = new import_tracker_1.ImportTracker();
94
+ emitter.emitInterface("AdminCreate", makeResolved(getType("Shape")), tracker);
95
+ expect(tracker.needsFindParams).toBe(false);
96
+ expect(tracker.needsBaseFilterable).toBe(false);
97
+ expect(tracker.needsOperatorMap).toBe(false);
98
+ });
99
+ it("sets needsFindParams when hasFindParams is true", () => {
100
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape {}`);
101
+ const emitter = new type_emitter_1.TypeEmitter(checker);
102
+ const tracker = new import_tracker_1.ImportTracker();
103
+ emitter.emitInterface("T", makeResolved(getType("Shape"), { hasFindParams: true }), tracker);
104
+ expect(tracker.needsFindParams).toBe(true);
105
+ });
106
+ it("sets needsBaseFilterable when hasBaseFilterable is true", () => {
107
+ const { checker, getType } = (0, ts_utils_1.createSingleFileProgram)(`interface Shape {}`);
108
+ const emitter = new type_emitter_1.TypeEmitter(checker);
109
+ const tracker = new import_tracker_1.ImportTracker();
110
+ emitter.emitInterface("T", makeResolved(getType("Shape"), { hasBaseFilterable: true }), tracker);
111
+ expect(tracker.needsBaseFilterable).toBe(true);
112
+ });
113
+ });
114
+ });
115
+ // ---------------------------------------------------------------------------
116
+ // TypeEmitter.assembleFile
117
+ // ---------------------------------------------------------------------------
118
+ describe("TypeEmitter.assembleFile", () => {
119
+ const outputFile = "/repo/packages/core/types/src/http/product/admin/payloads.ts";
120
+ it("joins multiple interfaces separated by blank lines", () => {
121
+ const interfaces = [
122
+ { name: "A", code: "export interface A { x: string }" },
123
+ { name: "B", code: "export interface B { y: number }" },
124
+ ];
125
+ const content = type_emitter_1.TypeEmitter.assembleFile(interfaces, new import_tracker_1.ImportTracker(), outputFile);
126
+ expect(content).toContain("export interface A");
127
+ expect(content).toContain("export interface B");
128
+ });
129
+ it("includes a FindParams import when needsFindParams is true", () => {
130
+ const tracker = new import_tracker_1.ImportTracker();
131
+ tracker.needsFindParams = true;
132
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T {}" }], tracker, outputFile);
133
+ expect(content).toMatch(/import \{ FindParams \} from ".*"/);
134
+ });
135
+ it("includes SelectParams in the common import when needsSelectParams is true", () => {
136
+ const tracker = new import_tracker_1.ImportTracker();
137
+ tracker.needsSelectParams = true;
138
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T {}" }], tracker, outputFile);
139
+ expect(content).toMatch(/import \{ SelectParams \} from ".*"/);
140
+ });
141
+ it("combines FindParams and SelectParams into a single common import", () => {
142
+ const tracker = new import_tracker_1.ImportTracker();
143
+ tracker.needsFindParams = true;
144
+ tracker.needsSelectParams = true;
145
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T {}" }], tracker, outputFile);
146
+ const importLines = content.split("\n").filter((l) => l.startsWith("import"));
147
+ expect(importLines).toHaveLength(1);
148
+ expect(importLines[0]).toContain("FindParams");
149
+ expect(importLines[0]).toContain("SelectParams");
150
+ });
151
+ it("includes a DAL import with BaseFilterable when needsBaseFilterable is true", () => {
152
+ const tracker = new import_tracker_1.ImportTracker();
153
+ tracker.needsBaseFilterable = true;
154
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T {}" }], tracker, outputFile);
155
+ expect(content).toMatch(/import \{ BaseFilterable \} from ".*"/);
156
+ });
157
+ it("combines BaseFilterable and OperatorMap into a single DAL import", () => {
158
+ const tracker = new import_tracker_1.ImportTracker();
159
+ tracker.needsBaseFilterable = true;
160
+ tracker.needsOperatorMap = true;
161
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T {}" }], tracker, outputFile);
162
+ const importLines = content.split("\n").filter((l) => l.startsWith("import"));
163
+ const dalImport = importLines.find((l) => l.includes("BaseFilterable"));
164
+ expect(dalImport).toBeDefined();
165
+ expect(dalImport).toContain("OperatorMap");
166
+ expect(importLines).toHaveLength(1);
167
+ });
168
+ it("produces no import lines when no imports are needed", () => {
169
+ const content = type_emitter_1.TypeEmitter.assembleFile([{ name: "T", code: "export interface T { x: string }" }], new import_tracker_1.ImportTracker(), outputFile);
170
+ expect(content.split("\n").filter((l) => l.startsWith("import"))).toHaveLength(0);
171
+ });
172
+ });
173
+ //# sourceMappingURL=type-emitter.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-emitter.spec.js","sourceRoot":"","sources":["../../src/__tests__/type-emitter.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=type-pipeline.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-pipeline.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/type-pipeline.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * End-to-end pipeline tests: simulated Zod schema source → emitted HTTP interface string.
5
+ *
6
+ * These tests exercise the full conversion path:
7
+ * SchemaExtractor.extract → TypeResolver.resolveSchemaType → TypeEmitter.emitInterface
8
+ *
9
+ * Rather than depending on the real Zod runtime, the source strings use
10
+ * plain TypeScript declarations that carry the same structural shape the TS
11
+ * compiler sees when resolving real Zod generics: an object type with
12
+ * `_input` and `_output` properties whose types are the inferred shapes.
13
+ */
14
+ const schema_extractor_1 = require("../core/schema-extractor");
15
+ const type_resolver_1 = require("../core/type-resolver");
16
+ const type_emitter_1 = require("../core/type-emitter");
17
+ const import_tracker_1 = require("../core/import-tracker");
18
+ const ts_utils_1 = require("./utils/ts-utils");
19
+ /**
20
+ * Runs the full schema → HTTP type pipeline against an in-memory TypeScript
21
+ * source file and returns the emitted interface for each extracted schema.
22
+ */
23
+ function runPipeline(source) {
24
+ const fileName = "validators.ts";
25
+ const { program, checker } = (0, ts_utils_1.createTestProgram)({ [fileName]: source });
26
+ const sourceFile = program.getSourceFile(fileName);
27
+ const extractor = new schema_extractor_1.SchemaExtractor(checker);
28
+ const resolver = new type_resolver_1.TypeResolver(checker);
29
+ const emitter = new type_emitter_1.TypeEmitter(checker);
30
+ const schemas = extractor.extract(sourceFile);
31
+ const results = [];
32
+ for (const schema of schemas) {
33
+ const resolved = resolver.resolveSchemaType(schema);
34
+ if (!resolved)
35
+ continue;
36
+ const tracker = new import_tracker_1.ImportTracker();
37
+ const code = emitter.emitInterface(schema.httpTypeName, resolved, tracker);
38
+ results.push({ name: schema.httpTypeName, code, tracker });
39
+ }
40
+ return results;
41
+ }
42
+ // ---------------------------------------------------------------------------
43
+ // Plain object schemas
44
+ // ---------------------------------------------------------------------------
45
+ describe("plain object schemas", () => {
46
+ it("emits required fields with their types", () => {
47
+ const [result] = runPipeline(`
48
+ export declare const AdminCreateProduct: {
49
+ _input: { title: string; handle: string }
50
+ _output: { title: string; handle: string }
51
+ }
52
+ `);
53
+ expect(result.code).toContain("export interface AdminCreateProduct");
54
+ expect(result.code).toContain("title: string");
55
+ expect(result.code).toContain("handle: string");
56
+ });
57
+ it("emits optional fields with the question-mark token", () => {
58
+ const [result] = runPipeline(`
59
+ export declare const AdminCreateProduct: {
60
+ _input: { title: string; description?: string }
61
+ _output: { title: string; description?: string }
62
+ }
63
+ `);
64
+ expect(result.code).toContain("title: string");
65
+ expect(result.code).toContain("description?: string");
66
+ });
67
+ it("emits nullable fields as T | null", () => {
68
+ const [result] = runPipeline(`
69
+ export declare const AdminCreateProduct: {
70
+ _input: { title: string | null }
71
+ _output: { title: string | null }
72
+ }
73
+ `);
74
+ expect(result.code).toContain("title: string | null");
75
+ });
76
+ it("emits array fields", () => {
77
+ const [result] = runPipeline(`
78
+ export declare const AdminCreateProduct: {
79
+ _input: { tags: string[] }
80
+ _output: { tags: string[] }
81
+ }
82
+ `);
83
+ expect(result.code).toContain("tags: string[]");
84
+ });
85
+ it("skips schemas without Admin or Store prefix", () => {
86
+ const results = runPipeline(`
87
+ export declare const CreateProduct: {
88
+ _input: { title: string }
89
+ _output: { title: string }
90
+ }
91
+ `);
92
+ expect(results).toHaveLength(0);
93
+ });
94
+ it("extracts multiple schemas from the same file", () => {
95
+ const results = runPipeline(`
96
+ export declare const AdminCreateProduct: {
97
+ _input: { title: string }
98
+ _output: { title: string }
99
+ }
100
+ export declare const AdminUpdateProduct: {
101
+ _input: { title?: string }
102
+ _output: { title?: string }
103
+ }
104
+ `);
105
+ expect(results).toHaveLength(2);
106
+ const names = results.map((r) => r.name);
107
+ expect(names).toContain("AdminCreateProduct");
108
+ expect(names).toContain("AdminUpdateProduct");
109
+ });
110
+ });
111
+ // ---------------------------------------------------------------------------
112
+ // createFindParams schemas
113
+ // ---------------------------------------------------------------------------
114
+ describe("createFindParams schemas", () => {
115
+ const FIND_PARAMS_SOURCE = `
116
+ declare function createFindParams(): {
117
+ _input: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean }
118
+ _output: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean }
119
+ }
120
+ `;
121
+ it("emits 'extends FindParams' when the chain includes createFindParams()", () => {
122
+ const [result] = runPipeline(`
123
+ ${FIND_PARAMS_SOURCE}
124
+ export const AdminGetProductsParams = createFindParams()
125
+ `);
126
+ expect(result.code).toContain("extends FindParams");
127
+ expect(result.tracker.needsFindParams).toBe(true);
128
+ });
129
+ it("omits FindParams fields (limit, offset, etc.) from the inline body", () => {
130
+ const [result] = runPipeline(`
131
+ ${FIND_PARAMS_SOURCE}
132
+ export const AdminGetProductsParams = createFindParams()
133
+ `);
134
+ expect(result.code).not.toContain("limit");
135
+ expect(result.code).not.toContain("offset");
136
+ expect(result.code).not.toContain("fields");
137
+ expect(result.code).not.toContain("order");
138
+ expect(result.code).not.toContain("with_deleted");
139
+ });
140
+ it("includes extra fields beyond the FindParams base", () => {
141
+ const [result] = runPipeline(`
142
+ declare function createFindParams(): {
143
+ _input: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean; q?: string }
144
+ _output: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean; q?: string }
145
+ }
146
+ export const AdminGetProductsParams = createFindParams()
147
+ `);
148
+ expect(result.code).toContain("extends FindParams");
149
+ expect(result.code).toContain("q?: string");
150
+ });
151
+ });
152
+ // ---------------------------------------------------------------------------
153
+ // createSelectParams schemas
154
+ // ---------------------------------------------------------------------------
155
+ describe("createSelectParams schemas", () => {
156
+ const SELECT_PARAMS_SOURCE = `
157
+ declare function createSelectParams(): {
158
+ _input: { fields?: string }
159
+ _output: { fields?: string }
160
+ }
161
+ `;
162
+ it("emits 'extends SelectParams' when the chain includes createSelectParams()", () => {
163
+ const [result] = runPipeline(`
164
+ ${SELECT_PARAMS_SOURCE}
165
+ export const AdminGetProductParams = createSelectParams()
166
+ `);
167
+ expect(result.code).toContain("extends SelectParams");
168
+ expect(result.tracker.needsSelectParams).toBe(true);
169
+ });
170
+ it("omits the 'fields' property from the inline body", () => {
171
+ const [result] = runPipeline(`
172
+ ${SELECT_PARAMS_SOURCE}
173
+ export const AdminGetProductParams = createSelectParams()
174
+ `);
175
+ expect(result.code).not.toContain("fields");
176
+ });
177
+ it("includes extra fields beyond SelectParams", () => {
178
+ const [result] = runPipeline(`
179
+ declare function createSelectParams(): {
180
+ _input: { fields?: string; expand?: string }
181
+ _output: { fields?: string; expand?: string }
182
+ }
183
+ export const AdminGetProductParams = createSelectParams()
184
+ `);
185
+ expect(result.code).toContain("extends SelectParams");
186
+ expect(result.code).toContain("expand?: string");
187
+ expect(result.code).not.toContain("fields");
188
+ });
189
+ it("does NOT emit SelectParams when createFindParams is also in the chain", () => {
190
+ const [result] = runPipeline(`
191
+ declare function createFindParams(): {
192
+ _input: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean }
193
+ _output: { limit?: number; offset?: number; fields?: string; order?: string; with_deleted?: boolean }
194
+ }
195
+ export const AdminGetProductsParams = createFindParams()
196
+ `);
197
+ expect(result.code).toContain("extends FindParams");
198
+ expect(result.code).not.toContain("SelectParams");
199
+ expect(result.tracker.needsSelectParams).toBe(false);
200
+ expect(result.tracker.needsFindParams).toBe(true);
201
+ });
202
+ });
203
+ // ---------------------------------------------------------------------------
204
+ // WithAdditionalData schemas
205
+ // ---------------------------------------------------------------------------
206
+ describe("WithAdditionalData schemas", () => {
207
+ it("resolves the inner schema type, excluding additional_data", () => {
208
+ const [result] = runPipeline(`
209
+ declare function WithAdditionalData<T>(schema: T): () => void
210
+ const CreateProduct: {
211
+ _input: { title: string; description?: string }
212
+ _output: { title: string; description?: string }
213
+ }
214
+ export const AdminCreateProduct = WithAdditionalData(CreateProduct)
215
+ `);
216
+ expect(result.code).toContain("export interface AdminCreateProduct");
217
+ expect(result.code).toContain("title: string");
218
+ expect(result.code).toContain("description?: string");
219
+ expect(result.code).not.toContain("additional_data");
220
+ });
221
+ });
222
+ // ---------------------------------------------------------------------------
223
+ // Transform schemas (ZodEffects)
224
+ // ---------------------------------------------------------------------------
225
+ describe("ZodEffects (transform) schemas", () => {
226
+ it("uses _input type rather than _output type for transforms", () => {
227
+ const [result] = runPipeline(`
228
+ interface ZodEffects<O, I> { _output: O; _input: I }
229
+ export declare const AdminCreateOrder: ZodEffects<
230
+ { id: string },
231
+ { raw_title: string; quantity: number }
232
+ >
233
+ `);
234
+ expect(result.code).toContain("raw_title: string");
235
+ expect(result.code).toContain("quantity: number");
236
+ expect(result.code).not.toContain("id: string");
237
+ });
238
+ });
239
+ //# sourceMappingURL=type-pipeline.spec.js.map