@powerlines/schema 0.8.67 → 0.9.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.
Files changed (55) hide show
  1. package/README.md +36 -22
  2. package/dist/bundle.d.cts +2 -2
  3. package/dist/bundle.d.cts.map +1 -1
  4. package/dist/bundle.d.mts +2 -2
  5. package/dist/bundle.d.mts.map +1 -1
  6. package/dist/bundle.mjs.map +1 -1
  7. package/dist/extract.cjs +200 -51
  8. package/dist/extract.d.cts +82 -16
  9. package/dist/extract.d.cts.map +1 -1
  10. package/dist/extract.d.mts +82 -16
  11. package/dist/extract.d.mts.map +1 -1
  12. package/dist/extract.mjs +198 -54
  13. package/dist/extract.mjs.map +1 -1
  14. package/dist/index.cjs +13 -2
  15. package/dist/index.d.cts +5 -4
  16. package/dist/index.d.mts +5 -4
  17. package/dist/index.mjs +4 -3
  18. package/dist/jtd.cjs +362 -0
  19. package/dist/jtd.d.cts +16 -0
  20. package/dist/jtd.d.cts.map +1 -0
  21. package/dist/jtd.d.mts +16 -0
  22. package/dist/jtd.d.mts.map +1 -0
  23. package/dist/jtd.mjs +361 -0
  24. package/dist/jtd.mjs.map +1 -0
  25. package/dist/reflection.cjs +229 -108
  26. package/dist/reflection.d.cts +17 -7
  27. package/dist/reflection.d.cts.map +1 -1
  28. package/dist/reflection.d.mts +17 -7
  29. package/dist/reflection.d.mts.map +1 -1
  30. package/dist/reflection.mjs +229 -108
  31. package/dist/reflection.mjs.map +1 -1
  32. package/dist/resolve.d.cts +5 -5
  33. package/dist/resolve.d.cts.map +1 -1
  34. package/dist/resolve.d.mts +5 -5
  35. package/dist/resolve.d.mts.map +1 -1
  36. package/dist/resolve.mjs.map +1 -1
  37. package/dist/type-checks.cjs +76 -0
  38. package/dist/type-checks.d.cts +43 -0
  39. package/dist/type-checks.d.cts.map +1 -0
  40. package/dist/type-checks.d.mts +43 -0
  41. package/dist/type-checks.d.mts.map +1 -0
  42. package/dist/type-checks.mjs +71 -0
  43. package/dist/type-checks.mjs.map +1 -0
  44. package/dist/types.d.cts +80 -24
  45. package/dist/types.d.cts.map +1 -1
  46. package/dist/types.d.mts +80 -24
  47. package/dist/types.d.mts.map +1 -1
  48. package/package.json +21 -19
  49. package/dist/is-schema-definition.cjs +0 -18
  50. package/dist/is-schema-definition.d.cts +0 -13
  51. package/dist/is-schema-definition.d.cts.map +0 -1
  52. package/dist/is-schema-definition.d.mts +0 -13
  53. package/dist/is-schema-definition.d.mts.map +0 -1
  54. package/dist/is-schema-definition.mjs +0 -17
  55. package/dist/is-schema-definition.mjs.map +0 -1
@@ -2,120 +2,146 @@ import { ReflectionKind, TypeNumberBrand } from "@powerlines/deepkit/vendor/type
2
2
 
3
3
  //#region src/reflection.ts
4
4
  /**
5
- * Converts a Deepkit type reflection into a JSON Schema representation.
5
+ * Maps a Deepkit numeric `brand` to the JTD numeric `type` keyword that best preserves the underlying width and signedness.
6
+ *
7
+ * @param brand - The Deepkit `TypeNumberBrand` of a numeric reflection, or `undefined` when no brand is set.
8
+ * @returns The JTD numeric `type` keyword to use.
9
+ */
10
+ function numberBrandToJtdType(brand) {
11
+ switch (brand) {
12
+ case TypeNumberBrand.integer: return "int32";
13
+ case TypeNumberBrand.int8: return "int8";
14
+ case TypeNumberBrand.uint8: return "uint8";
15
+ case TypeNumberBrand.int16: return "int16";
16
+ case TypeNumberBrand.uint16: return "uint16";
17
+ case TypeNumberBrand.int32: return "int32";
18
+ case TypeNumberBrand.uint32: return "uint32";
19
+ case TypeNumberBrand.float:
20
+ case TypeNumberBrand.float32: return "float32";
21
+ case TypeNumberBrand.float64: return "float64";
22
+ case void 0:
23
+ default: return "float64";
24
+ }
25
+ }
26
+ /**
27
+ * Attaches a `description` annotation to a JTD form's `metadata` bag.
28
+ *
29
+ * @param form - The JTD form to decorate.
30
+ * @param description - The description text, or `undefined` to skip.
31
+ * @returns The same JTD form, decorated when a description was provided.
32
+ */
33
+ function attachDescription(form, description) {
34
+ if (!description) return form;
35
+ const metadata = form.metadata ?? {};
36
+ metadata.description = description;
37
+ form.metadata = metadata;
38
+ return form;
39
+ }
40
+ /**
41
+ * Converts a Deepkit type reflection into a JSON Type Definition (RFC 8927) form suitable for AJV's JTD validator.
42
+ *
43
+ * @remarks
44
+ * Some TypeScript constructs have no direct JTD equivalent and are handled with the closest available form:
45
+ *
46
+ * - `null` and `undefined` become the empty JTD form with `nullable: true`.
47
+ * - Unions of primitives that cannot be expressed as a JTD enum collapse to the empty form (which validates any value).
48
+ * - String/number/bigint literal unions are emitted as a JTD enum (non-string members are stringified, as JTD requires string enum members).
49
+ * - Tuples are emitted as a JTD elements form whose element schema is the single tuple member type, or the empty schema for mixed tuples.
50
+ * - `Date` is emitted as `{ type: "timestamp" }`.
51
+ * - Discriminated unions of object literals (a shared string-literal tag property) are emitted as a JTD discriminator form.
6
52
  *
7
53
  * @param reflection - The Deepkit type reflection to convert.
8
- * @returns The corresponding JSON Schema representation, or `undefined` if the type cannot be represented.
54
+ * @returns The corresponding JTD form, or `undefined` if the type cannot be represented.
9
55
  */
10
56
  function reflectionToJsonSchema(reflection) {
57
+ return reflectionToJtd(reflection);
58
+ }
59
+ /**
60
+ * Internal worker that performs the recursive Deepkit reflection → JTD conversion.
61
+ *
62
+ * @param reflection - The Deepkit type reflection to convert.
63
+ * @returns The corresponding JTD form, or `undefined` if the type cannot be represented.
64
+ */
65
+ function reflectionToJtd(reflection) {
11
66
  switch (reflection.kind) {
12
67
  case ReflectionKind.any:
13
68
  case ReflectionKind.unknown:
14
69
  case ReflectionKind.void:
15
70
  case ReflectionKind.object: return {};
16
- case ReflectionKind.never:
17
- case ReflectionKind.undefined: return { not: {} };
18
- case ReflectionKind.null: return { type: "null" };
71
+ case ReflectionKind.never: return;
72
+ case ReflectionKind.undefined:
73
+ case ReflectionKind.null: return { nullable: true };
19
74
  case ReflectionKind.string: return { type: "string" };
20
75
  case ReflectionKind.boolean: return { type: "boolean" };
21
- case ReflectionKind.number: {
22
- const brand = reflection.brand;
23
- return { type: brand !== void 0 && brand >= TypeNumberBrand.integer && brand <= TypeNumberBrand.uint32 ? "integer" : "number" };
24
- }
25
- case ReflectionKind.bigint: return {
26
- type: "integer",
27
- format: "int64"
28
- };
76
+ case ReflectionKind.number: return { type: numberBrandToJtdType(reflection.brand) };
77
+ case ReflectionKind.bigint: return { type: "float64" };
29
78
  case ReflectionKind.regexp: return { type: "string" };
30
79
  case ReflectionKind.literal: {
31
80
  const { literal } = reflection;
32
- if (typeof literal === "string") return {
33
- type: "string",
34
- const: literal
35
- };
36
- if (typeof literal === "number") return {
37
- type: Number.isInteger(literal) ? "integer" : "number",
38
- const: literal
39
- };
40
- if (typeof literal === "boolean") return {
41
- type: "boolean",
42
- const: literal
43
- };
44
- if (typeof literal === "bigint") return {
45
- type: "integer",
46
- format: "int64"
47
- };
48
- if (literal instanceof RegExp) return {
49
- type: "string",
50
- pattern: literal.source
51
- };
81
+ if (typeof literal === "string") return { enum: [literal] };
82
+ if (typeof literal === "number" || typeof literal === "bigint") return { enum: [String(literal)] };
83
+ if (typeof literal === "boolean") return { type: "boolean" };
84
+ if (literal instanceof RegExp) return { type: "string" };
52
85
  return {};
53
86
  }
54
87
  case ReflectionKind.templateLiteral: return { type: "string" };
55
88
  case ReflectionKind.enum: {
56
- const values = reflection.values.filter((value) => typeof value === "string" || typeof value === "number");
57
- const allStrings = values.every((value) => typeof value === "string");
58
- const allNumbers = values.every((value) => typeof value === "number");
59
- return {
60
- type: allStrings ? "string" : allNumbers ? "number" : ["string", "number"],
61
- enum: values
62
- };
89
+ const values = reflection.values.filter((value) => typeof value === "string" || typeof value === "number").map((value) => String(value));
90
+ const unique = Array.from(new Set(values));
91
+ if (unique.length === 0) return {};
92
+ return { enum: unique };
63
93
  }
64
- case ReflectionKind.array: {
65
- const items = reflectionToJsonSchema(reflection.type);
66
- return items ? {
67
- type: "array",
68
- items
69
- } : { type: "array" };
94
+ case ReflectionKind.array: return { elements: reflectionToJtd(reflection.type) ?? {} };
95
+ case ReflectionKind.tuple: {
96
+ const items = reflection.types.map((member) => reflectionToJtd(member.type)).filter((item) => item !== void 0);
97
+ if (items.length === 0) return { elements: {} };
98
+ if (items.length === 1) return { elements: items[0] };
99
+ return { elements: {} };
70
100
  }
71
- case ReflectionKind.tuple: return {
72
- type: "array",
73
- items: reflection.types.map((member) => reflectionToJsonSchema(member.type)).filter((item) => item !== void 0),
74
- minItems: reflection.types.filter((member) => !member.optional).length,
75
- maxItems: reflection.types.length
76
- };
77
101
  case ReflectionKind.union: {
78
- const anyOf = reflection.types.map((inner) => reflectionToJsonSchema(inner)).filter((item) => item !== void 0);
79
- if (anyOf.length === 0) return;
80
- if (anyOf.length === 1) return anyOf[0];
81
- return { anyOf };
102
+ const branches = reflection.types.map((inner) => reflectionToJtd(inner)).filter((item) => item !== void 0);
103
+ const nullable = reflection.types.some((inner) => inner.kind === ReflectionKind.null || inner.kind === ReflectionKind.undefined);
104
+ const nonNull = branches.filter((b) => !isPureNullable(b));
105
+ if (nonNull.length === 0) return { nullable: true };
106
+ if (nonNull.length === 1) {
107
+ const only = nonNull[0];
108
+ if (nullable) only.nullable = true;
109
+ return only;
110
+ }
111
+ if (nonNull.every(isEnumForm)) {
112
+ const form = { enum: Array.from(new Set(nonNull.flatMap((b) => b.enum))) };
113
+ if (nullable) form.nullable = true;
114
+ return form;
115
+ }
116
+ const discriminator = tryReflectionDiscriminator(reflection.types);
117
+ if (discriminator) {
118
+ if (nullable) discriminator.nullable = true;
119
+ return discriminator;
120
+ }
121
+ const fallback = {};
122
+ if (nullable) fallback.nullable = true;
123
+ return fallback;
82
124
  }
83
125
  case ReflectionKind.intersection: {
84
- const allOf = reflection.types.map((inner) => reflectionToJsonSchema(inner)).filter((item) => item !== void 0);
85
- if (allOf.length === 0) return;
86
- if (allOf.length === 1) return allOf[0];
87
- return { allOf };
126
+ const members = reflection.types.map((inner) => reflectionToJtd(inner)).filter((item) => item !== void 0);
127
+ if (members.length === 0) return;
128
+ if (members.length === 1) return members[0];
129
+ if (members.every(isPropertiesForm)) return mergePropertiesForms(members);
130
+ return members[0];
88
131
  }
89
- case ReflectionKind.promise: return reflectionToJsonSchema(reflection.type);
90
- case ReflectionKind.objectLiteral: return objectReflectionToJsonSchema(reflection);
132
+ case ReflectionKind.promise: return reflectionToJtd(reflection.type);
133
+ case ReflectionKind.objectLiteral: return objectReflectionToJtd(reflection);
91
134
  case ReflectionKind.class: switch (reflection.classType?.name) {
92
- case "Date": return {
93
- type: "string",
94
- format: "date-time"
95
- };
135
+ case "Date": return { type: "timestamp" };
96
136
  case "RegExp": return { type: "string" };
97
- case "URL": return {
98
- type: "string",
99
- format: "uri"
100
- };
137
+ case "URL": return { type: "string" };
101
138
  case "Set": {
102
139
  const itemType = reflection.arguments?.[0];
103
- const items = itemType ? reflectionToJsonSchema(itemType) : void 0;
104
- return items ? {
105
- type: "array",
106
- uniqueItems: true,
107
- items
108
- } : {
109
- type: "array",
110
- uniqueItems: true
111
- };
140
+ return { elements: (itemType ? reflectionToJtd(itemType) : void 0) ?? {} };
112
141
  }
113
142
  case "Map": {
114
143
  const valueType = reflection.arguments?.[1];
115
- const additionalProperties = valueType ? reflectionToJsonSchema(valueType) : void 0;
116
- const schema = { type: "object" };
117
- if (additionalProperties) schema.additionalProperties = additionalProperties;
118
- return schema;
144
+ return { values: (valueType ? reflectionToJtd(valueType) : void 0) ?? {} };
119
145
  }
120
146
  case "Uint8Array":
121
147
  case "Uint8ClampedArray":
@@ -127,12 +153,9 @@ function reflectionToJsonSchema(reflection) {
127
153
  case "Float32Array":
128
154
  case "Float64Array":
129
155
  case "BigInt64Array":
130
- case "BigUint64Array": return {
131
- type: "string",
132
- contentEncoding: "base64"
133
- };
156
+ case "BigUint64Array": return { type: "string" };
134
157
  case void 0:
135
- default: return objectReflectionToJsonSchema(reflection);
158
+ default: return objectReflectionToJtd(reflection);
136
159
  }
137
160
  case ReflectionKind.symbol:
138
161
  case ReflectionKind.property:
@@ -152,36 +175,134 @@ function reflectionToJsonSchema(reflection) {
152
175
  }
153
176
  }
154
177
  /**
155
- * Builds a JSON Schema object representation from a Deepkit class or object literal type.
178
+ * Tests whether a JTD form is an enum form.
179
+ *
180
+ * @param form - The JTD form to inspect.
181
+ * @returns `true` if the form is a JTD enum form.
182
+ */
183
+ function isEnumForm(form) {
184
+ return Array.isArray(form.enum);
185
+ }
186
+ /**
187
+ * Tests whether a JTD form is a properties form (object).
188
+ *
189
+ * @param form - The JTD form to inspect.
190
+ * @returns `true` if the form is a JTD properties form.
191
+ */
192
+ function isPropertiesForm(form) {
193
+ return "properties" in form || "optionalProperties" in form;
194
+ }
195
+ /**
196
+ * Tests whether a JTD form is the empty `{ nullable: true }` placeholder.
197
+ *
198
+ * @param form - The JTD form to inspect.
199
+ * @returns `true` if the form has no shape constraints beyond `nullable`.
200
+ */
201
+ function isPureNullable(form) {
202
+ return Object.keys(form).filter((k) => k !== "nullable" && k !== "metadata").length === 0 && form.nullable === true;
203
+ }
204
+ /**
205
+ * Shallow-merges two JTD properties forms, unioning their `properties` and `optionalProperties` maps.
206
+ *
207
+ * @param forms - The JTD properties forms to merge.
208
+ * @returns The merged JTD properties form.
209
+ */
210
+ function mergePropertiesForms(forms) {
211
+ const merged = {
212
+ properties: {},
213
+ optionalProperties: {}
214
+ };
215
+ for (const form of forms) {
216
+ const p = form.properties;
217
+ const o = form.optionalProperties;
218
+ if (p) Object.assign(merged.properties, p);
219
+ if (o) Object.assign(merged.optionalProperties, o);
220
+ if (form.additionalProperties) merged.additionalProperties = true;
221
+ }
222
+ const hasProperties = Object.keys(merged.properties).length > 0;
223
+ const hasOptional = Object.keys(merged.optionalProperties).length > 0;
224
+ const result = {};
225
+ if (hasProperties) result.properties = merged.properties;
226
+ else if (!hasOptional) result.properties = {};
227
+ if (hasOptional) result.optionalProperties = merged.optionalProperties;
228
+ if (merged.additionalProperties) result.additionalProperties = true;
229
+ return result;
230
+ }
231
+ /**
232
+ * Detects whether a Deepkit union represents a tagged union and, when so, emits the corresponding JTD discriminator form.
233
+ *
234
+ * @param types - The Deepkit reflection types that make up the union branches.
235
+ * @returns A JTD discriminator form if every non-null branch is an object literal that shares a string-literal tag property, otherwise `undefined`.
236
+ */
237
+ function tryReflectionDiscriminator(types) {
238
+ const nonNullTypes = types.filter((t) => t.kind !== ReflectionKind.null && t.kind !== ReflectionKind.undefined);
239
+ const objectBranches = nonNullTypes.filter((t) => t.kind === ReflectionKind.objectLiteral || t.kind === ReflectionKind.class);
240
+ if (objectBranches.length < 2 || objectBranches.length !== nonNullTypes.length) return;
241
+ let tagKey;
242
+ const mapping = {};
243
+ for (const branch of objectBranches) {
244
+ const literalProps = [];
245
+ for (const member of branch.types) if ((member.kind === ReflectionKind.property || member.kind === ReflectionKind.propertySignature) && typeof member.name === "string" && member.type.kind === ReflectionKind.literal && typeof member.type.literal === "string") literalProps.push({
246
+ name: member.name,
247
+ literal: member.type.literal
248
+ });
249
+ if (literalProps.length === 0) return;
250
+ const first = literalProps[0];
251
+ if (!tagKey) tagKey = first.name;
252
+ else if (tagKey !== first.name) return;
253
+ const body = objectReflectionToJtd({
254
+ ...branch,
255
+ types: branch.types.filter((member) => !((member.kind === ReflectionKind.property || member.kind === ReflectionKind.propertySignature) && member.name === tagKey))
256
+ });
257
+ if (!body || !isPropertiesForm(body)) return;
258
+ mapping[first.literal] = body;
259
+ }
260
+ if (!tagKey) return;
261
+ return {
262
+ discriminator: tagKey,
263
+ mapping
264
+ };
265
+ }
266
+ /**
267
+ * Builds a JTD properties form from a Deepkit class or object literal type.
156
268
  *
157
269
  * @param type - The class or object literal type whose members should be serialized.
158
- * @returns A JSON Schema object describing the type's properties.
270
+ * @returns A JTD properties form describing the type's members.
159
271
  */
160
272
  function objectReflectionToJsonSchema(type) {
273
+ return objectReflectionToJtd(type);
274
+ }
275
+ /**
276
+ * Internal worker that produces a JTD properties form (or `values` form for index signatures alone) from a Deepkit object-like type.
277
+ *
278
+ * @param type - The class or object literal type whose members should be serialized.
279
+ * @returns A JTD properties or values form describing the type's members.
280
+ */
281
+ function objectReflectionToJtd(type) {
161
282
  const properties = {};
162
- const required = [];
163
- let additionalProperties;
283
+ const optionalProperties = {};
284
+ let indexValueSchema;
164
285
  const description = "description" in type && typeof type.description === "string" ? type.description : void 0;
165
286
  for (const member of type.types) if (member.kind === ReflectionKind.property || member.kind === ReflectionKind.propertySignature) {
166
- const property = member;
167
- if (typeof property.name !== "string") continue;
168
- const propertySchema = reflectionToJsonSchema(property.type);
287
+ if (typeof member.name !== "string") continue;
288
+ const propertySchema = reflectionToJtd(member.type);
169
289
  if (!propertySchema) continue;
170
- if (typeof property.description === "string") propertySchema.description = property.description;
171
- properties[property.name] = propertySchema;
172
- if (!property.optional) required.push(property.name);
290
+ if (typeof member.description === "string") attachDescription(propertySchema, member.description);
291
+ if (member.optional) optionalProperties[member.name] = propertySchema;
292
+ else properties[member.name] = propertySchema;
173
293
  } else if (member.kind === ReflectionKind.indexSignature) {
174
- const valueSchema = reflectionToJsonSchema(member.type);
175
- if (valueSchema) additionalProperties = valueSchema;
294
+ const valueSchema = reflectionToJtd(member.type);
295
+ if (valueSchema) indexValueSchema = valueSchema;
176
296
  }
177
- const schema = {
178
- type: "object",
179
- properties
180
- };
181
- if (required.length > 0) schema.required = required;
182
- if (additionalProperties !== void 0) schema.additionalProperties = additionalProperties;
183
- if (description) schema.description = description;
184
- return schema;
297
+ const hasProperties = Object.keys(properties).length > 0;
298
+ const hasOptional = Object.keys(optionalProperties).length > 0;
299
+ if (!hasProperties && !hasOptional && indexValueSchema) return attachDescription({ values: indexValueSchema }, description);
300
+ const form = {};
301
+ if (hasProperties) form.properties = properties;
302
+ else if (!hasOptional) form.properties = {};
303
+ if (hasOptional) form.optionalProperties = optionalProperties;
304
+ if (indexValueSchema) form.additionalProperties = true;
305
+ return attachDescription(form, description);
185
306
  }
186
307
 
187
308
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"reflection.mjs","names":["indexSignature"],"sources":["../src/reflection.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { Type, TypeClass } from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionKind,\n TypeNumberBrand,\n TypeObjectLiteral\n} from \"@powerlines/deepkit/vendor/type\";\nimport { JsonSchema7Type } from \"@stryke/json/types\";\n\n/**\n * Converts a Deepkit type reflection into a JSON Schema representation.\n *\n * @param reflection - The Deepkit type reflection to convert.\n * @returns The corresponding JSON Schema representation, or `undefined` if the type cannot be represented.\n */\nexport function reflectionToJsonSchema(\n reflection: Type\n): JsonSchema7Type | undefined {\n switch (reflection.kind) {\n case ReflectionKind.any:\n case ReflectionKind.unknown:\n case ReflectionKind.void:\n case ReflectionKind.object:\n return {};\n case ReflectionKind.never:\n case ReflectionKind.undefined:\n return { not: {} };\n case ReflectionKind.null:\n return { type: \"null\" };\n case ReflectionKind.string:\n return { type: \"string\" };\n case ReflectionKind.boolean:\n return { type: \"boolean\" };\n case ReflectionKind.number: {\n const brand = reflection.brand;\n const isInteger =\n brand !== undefined &&\n brand >= TypeNumberBrand.integer &&\n brand <= TypeNumberBrand.uint32;\n\n return { type: isInteger ? \"integer\" : \"number\" };\n }\n case ReflectionKind.bigint:\n return { type: \"integer\", format: \"int64\" };\n case ReflectionKind.regexp:\n return { type: \"string\" };\n case ReflectionKind.literal: {\n const { literal } = reflection;\n if (typeof literal === \"string\") {\n return { type: \"string\", const: literal };\n }\n if (typeof literal === \"number\") {\n return {\n type: Number.isInteger(literal) ? \"integer\" : \"number\",\n const: literal\n };\n }\n if (typeof literal === \"boolean\") {\n return { type: \"boolean\", const: literal };\n }\n if (typeof literal === \"bigint\") {\n return { type: \"integer\", format: \"int64\" };\n }\n if (literal instanceof RegExp) {\n return { type: \"string\", pattern: literal.source };\n }\n return {};\n }\n case ReflectionKind.templateLiteral:\n return { type: \"string\" };\n case ReflectionKind.enum: {\n const values = reflection.values.filter(\n (value): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\"\n );\n const allStrings = values.every(value => typeof value === \"string\");\n const allNumbers = values.every(value => typeof value === \"number\");\n\n return {\n type: allStrings\n ? \"string\"\n : allNumbers\n ? \"number\"\n : [\"string\", \"number\"],\n enum: values\n };\n }\n case ReflectionKind.array: {\n const items = reflectionToJsonSchema(reflection.type);\n\n return items ? { type: \"array\", items } : { type: \"array\" };\n }\n case ReflectionKind.tuple: {\n const items = reflection.types\n .map(member => reflectionToJsonSchema(member.type))\n .filter((item): item is JsonSchema7Type => item !== undefined);\n const required = reflection.types.filter(\n member => !member.optional\n ).length;\n\n return {\n type: \"array\",\n items,\n minItems: required,\n maxItems: reflection.types.length\n };\n }\n case ReflectionKind.union: {\n const anyOf = reflection.types\n .map(inner => reflectionToJsonSchema(inner))\n .filter((item): item is JsonSchema7Type => item !== undefined);\n if (anyOf.length === 0) {\n return undefined;\n }\n if (anyOf.length === 1) {\n return anyOf[0];\n }\n return { anyOf };\n }\n case ReflectionKind.intersection: {\n const allOf = reflection.types\n .map(inner => reflectionToJsonSchema(inner))\n .filter((item): item is JsonSchema7Type => item !== undefined);\n if (allOf.length === 0) {\n return undefined;\n }\n if (allOf.length === 1) {\n return allOf[0];\n }\n return { allOf };\n }\n case ReflectionKind.promise:\n return reflectionToJsonSchema(reflection.type);\n case ReflectionKind.objectLiteral:\n return objectReflectionToJsonSchema(reflection);\n case ReflectionKind.class: {\n const classType = reflection.classType as { name?: string } | undefined;\n const className = classType?.name;\n switch (className) {\n case \"Date\":\n return { type: \"string\", format: \"date-time\" };\n case \"RegExp\":\n return { type: \"string\" };\n case \"URL\":\n return { type: \"string\", format: \"uri\" };\n case \"Set\": {\n const itemType = reflection.arguments?.[0];\n const items = itemType ? reflectionToJsonSchema(itemType) : undefined;\n\n return items\n ? { type: \"array\", uniqueItems: true, items }\n : { type: \"array\", uniqueItems: true };\n }\n case \"Map\": {\n const valueType = reflection.arguments?.[1];\n const additionalProperties = valueType\n ? reflectionToJsonSchema(valueType)\n : undefined;\n const schema = { type: \"object\" } as JsonSchema7Type;\n if (additionalProperties) {\n (\n schema as { additionalProperties?: JsonSchema7Type }\n ).additionalProperties = additionalProperties;\n }\n return schema;\n }\n case \"Uint8Array\":\n case \"Uint8ClampedArray\":\n case \"Uint16Array\":\n case \"Uint32Array\":\n case \"Int8Array\":\n case \"Int16Array\":\n case \"Int32Array\":\n case \"Float32Array\":\n case \"Float64Array\":\n case \"BigInt64Array\":\n case \"BigUint64Array\":\n return { type: \"string\", contentEncoding: \"base64\" };\n case undefined:\n default:\n return objectReflectionToJsonSchema(reflection);\n }\n }\n\n case ReflectionKind.symbol:\n case ReflectionKind.property:\n case ReflectionKind.method:\n case ReflectionKind.function:\n case ReflectionKind.parameter:\n case ReflectionKind.typeParameter:\n case ReflectionKind.tupleMember:\n case ReflectionKind.enumMember:\n case ReflectionKind.rest:\n case ReflectionKind.indexSignature:\n case ReflectionKind.propertySignature:\n case ReflectionKind.methodSignature:\n case ReflectionKind.infer:\n case ReflectionKind.callSignature:\n default:\n return undefined;\n }\n}\n\n/**\n * Builds a JSON Schema object representation from a Deepkit class or object literal type.\n *\n * @param type - The class or object literal type whose members should be serialized.\n * @returns A JSON Schema object describing the type's properties.\n */\nexport function objectReflectionToJsonSchema(\n type: TypeObjectLiteral | TypeClass\n): JsonSchema7Type {\n const properties: Record<string, JsonSchema7Type> = {};\n const required: string[] = [];\n let additionalProperties: JsonSchema7Type | boolean | undefined;\n const description =\n \"description\" in type && typeof type.description === \"string\"\n ? type.description\n : undefined;\n\n for (const member of type.types) {\n if (\n member.kind === ReflectionKind.property ||\n member.kind === ReflectionKind.propertySignature\n ) {\n const property = member;\n if (typeof property.name !== \"string\") {\n continue;\n }\n const propertySchema = reflectionToJsonSchema(property.type);\n if (!propertySchema) {\n continue;\n }\n if (typeof property.description === \"string\") {\n (propertySchema as { description?: string }).description =\n property.description;\n }\n properties[property.name] = propertySchema;\n if (!property.optional) {\n required.push(property.name);\n }\n } else if (member.kind === ReflectionKind.indexSignature) {\n const indexSignature = member;\n const valueSchema = reflectionToJsonSchema(indexSignature.type);\n if (valueSchema) {\n additionalProperties = valueSchema;\n }\n }\n }\n\n const schema = {\n type: \"object\",\n properties\n } as JsonSchema7Type;\n\n if (required.length > 0) {\n (schema as { required?: string[] }).required = required;\n }\n if (additionalProperties !== undefined) {\n (\n schema as { additionalProperties?: JsonSchema7Type | boolean }\n ).additionalProperties = additionalProperties;\n }\n if (description) {\n (schema as { description?: string }).description = description;\n }\n\n return schema;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"reflection.mjs","names":[],"sources":["../src/reflection.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type { Type, TypeClass } from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionKind,\n TypeNumberBrand,\n TypeObjectLiteral\n} from \"@powerlines/deepkit/vendor/type\";\nimport { JTDSchemaType, SomeJTDSchemaType } from \"ajv/dist/types/jtd-schema\";\n\n/**\n * Maps a Deepkit numeric `brand` to the JTD numeric `type` keyword that best preserves the underlying width and signedness.\n *\n * @param brand - The Deepkit `TypeNumberBrand` of a numeric reflection, or `undefined` when no brand is set.\n * @returns The JTD numeric `type` keyword to use.\n */\nfunction numberBrandToJtdType(\n brand: TypeNumberBrand | undefined\n):\n | \"int8\"\n | \"uint8\"\n | \"int16\"\n | \"uint16\"\n | \"int32\"\n | \"uint32\"\n | \"float32\"\n | \"float64\" {\n switch (brand) {\n case TypeNumberBrand.integer:\n return \"int32\";\n case TypeNumberBrand.int8:\n return \"int8\";\n case TypeNumberBrand.uint8:\n return \"uint8\";\n case TypeNumberBrand.int16:\n return \"int16\";\n case TypeNumberBrand.uint16:\n return \"uint16\";\n case TypeNumberBrand.int32:\n return \"int32\";\n case TypeNumberBrand.uint32:\n return \"uint32\";\n case TypeNumberBrand.float:\n case TypeNumberBrand.float32:\n return \"float32\";\n case TypeNumberBrand.float64:\n return \"float64\";\n case undefined:\n default:\n return \"float64\";\n }\n}\n\n/**\n * Attaches a `description` annotation to a JTD form's `metadata` bag.\n *\n * @param form - The JTD form to decorate.\n * @param description - The description text, or `undefined` to skip.\n * @returns The same JTD form, decorated when a description was provided.\n */\nfunction attachDescription<S extends SomeJTDSchemaType>(\n form: S,\n description: string | undefined\n): S {\n if (!description) {\n return form;\n }\n const metadata =\n (form as { metadata?: Record<string, unknown> }).metadata ?? {};\n metadata.description = description;\n (form as { metadata?: Record<string, unknown> }).metadata = metadata;\n return form;\n}\n\n/**\n * Converts a Deepkit type reflection into a JSON Type Definition (RFC 8927) form suitable for AJV's JTD validator.\n *\n * @remarks\n * Some TypeScript constructs have no direct JTD equivalent and are handled with the closest available form:\n *\n * - `null` and `undefined` become the empty JTD form with `nullable: true`.\n * - Unions of primitives that cannot be expressed as a JTD enum collapse to the empty form (which validates any value).\n * - String/number/bigint literal unions are emitted as a JTD enum (non-string members are stringified, as JTD requires string enum members).\n * - Tuples are emitted as a JTD elements form whose element schema is the single tuple member type, or the empty schema for mixed tuples.\n * - `Date` is emitted as `{ type: \"timestamp\" }`.\n * - Discriminated unions of object literals (a shared string-literal tag property) are emitted as a JTD discriminator form.\n *\n * @param reflection - The Deepkit type reflection to convert.\n * @returns The corresponding JTD form, or `undefined` if the type cannot be represented.\n */\nexport function reflectionToJsonSchema<\n T = unknown,\n D extends Record<string, unknown> = Record<string, unknown>\n>(reflection: Type): JTDSchemaType<T, D> | undefined {\n const result = reflectionToJtd(reflection);\n\n return result as JTDSchemaType<T, D> | undefined;\n}\n\n/**\n * Internal worker that performs the recursive Deepkit reflection → JTD conversion.\n *\n * @param reflection - The Deepkit type reflection to convert.\n * @returns The corresponding JTD form, or `undefined` if the type cannot be represented.\n */\nfunction reflectionToJtd(reflection: Type): SomeJTDSchemaType | undefined {\n switch (reflection.kind) {\n case ReflectionKind.any:\n case ReflectionKind.unknown:\n case ReflectionKind.void:\n case ReflectionKind.object:\n return {};\n case ReflectionKind.never:\n return undefined;\n case ReflectionKind.undefined:\n case ReflectionKind.null:\n return { nullable: true };\n case ReflectionKind.string:\n return { type: \"string\" };\n case ReflectionKind.boolean:\n return { type: \"boolean\" };\n case ReflectionKind.number:\n return { type: numberBrandToJtdType(reflection.brand) };\n case ReflectionKind.bigint:\n // JTD has no native 64-bit integer type — float64 is the widest numeric form.\n return { type: \"float64\" };\n case ReflectionKind.regexp:\n return { type: \"string\" };\n case ReflectionKind.literal: {\n const { literal } = reflection;\n if (typeof literal === \"string\") {\n return { enum: [literal] };\n }\n if (typeof literal === \"number\" || typeof literal === \"bigint\") {\n return { enum: [String(literal)] };\n }\n if (typeof literal === \"boolean\") {\n // JTD has no boolean literal — emit the type form.\n return { type: \"boolean\" };\n }\n if (literal instanceof RegExp) {\n return { type: \"string\" };\n }\n return {};\n }\n case ReflectionKind.templateLiteral:\n return { type: \"string\" };\n case ReflectionKind.enum: {\n const values = reflection.values\n .filter(\n (value): value is string | number =>\n typeof value === \"string\" || typeof value === \"number\"\n )\n .map(value => String(value));\n const unique = Array.from(new Set(values));\n if (unique.length === 0) {\n return {};\n }\n return { enum: unique };\n }\n case ReflectionKind.array: {\n const items = reflectionToJtd(reflection.type);\n\n return { elements: items ?? {} };\n }\n case ReflectionKind.tuple: {\n const items = reflection.types\n .map(member => reflectionToJtd(member.type))\n .filter((item): item is SomeJTDSchemaType => item !== undefined);\n if (items.length === 0) {\n return { elements: {} };\n }\n if (items.length === 1) {\n return { elements: items[0]! };\n }\n // JTD has no tuple form — accept any element shape.\n return { elements: {} };\n }\n case ReflectionKind.union: {\n const branches = reflection.types\n .map(inner => reflectionToJtd(inner))\n .filter((item): item is SomeJTDSchemaType => item !== undefined);\n\n const nullable = reflection.types.some(\n inner =>\n inner.kind === ReflectionKind.null ||\n inner.kind === ReflectionKind.undefined\n );\n const nonNull = branches.filter(b => !isPureNullable(b));\n\n if (nonNull.length === 0) {\n return { nullable: true };\n }\n if (nonNull.length === 1) {\n const only = nonNull[0]!;\n if (nullable) {\n (only as { nullable?: boolean }).nullable = true;\n }\n return only;\n }\n\n // String-enum union: combine all enum branches into one JTD enum.\n if (nonNull.every(isEnumForm)) {\n const merged = Array.from(\n new Set(nonNull.flatMap(b => (b as { enum: string[] }).enum))\n );\n const form: SomeJTDSchemaType = { enum: merged };\n if (nullable) {\n (form as { nullable?: boolean }).nullable = true;\n }\n return form;\n }\n\n // Discriminated union of object literals: detect a shared string-literal tag.\n const discriminator = tryReflectionDiscriminator(reflection.types);\n if (discriminator) {\n if (nullable) {\n (discriminator as { nullable?: boolean }).nullable = true;\n }\n return discriminator;\n }\n\n // Fallback — JTD has no general union; allow any value.\n const fallback: SomeJTDSchemaType = {};\n if (nullable) {\n (fallback as { nullable?: boolean }).nullable = true;\n }\n return fallback;\n }\n case ReflectionKind.intersection: {\n const members = reflection.types\n .map(inner => reflectionToJtd(inner))\n .filter((item): item is SomeJTDSchemaType => item !== undefined);\n if (members.length === 0) {\n return undefined;\n }\n if (members.length === 1) {\n return members[0]!;\n }\n if (members.every(isPropertiesForm)) {\n return mergePropertiesForms(members);\n }\n return members[0]!;\n }\n case ReflectionKind.promise:\n return reflectionToJtd(reflection.type);\n case ReflectionKind.objectLiteral:\n return objectReflectionToJtd(reflection);\n case ReflectionKind.class: {\n const classType = reflection.classType as { name?: string } | undefined;\n const className = classType?.name;\n switch (className) {\n case \"Date\":\n return { type: \"timestamp\" };\n case \"RegExp\":\n return { type: \"string\" };\n case \"URL\":\n return { type: \"string\" };\n case \"Set\": {\n const itemType = reflection.arguments?.[0];\n const items = itemType ? reflectionToJtd(itemType) : undefined;\n\n return { elements: items ?? {} };\n }\n case \"Map\": {\n const valueType = reflection.arguments?.[1];\n const values = valueType ? reflectionToJtd(valueType) : undefined;\n\n return { values: values ?? {} };\n }\n case \"Uint8Array\":\n case \"Uint8ClampedArray\":\n case \"Uint16Array\":\n case \"Uint32Array\":\n case \"Int8Array\":\n case \"Int16Array\":\n case \"Int32Array\":\n case \"Float32Array\":\n case \"Float64Array\":\n case \"BigInt64Array\":\n case \"BigUint64Array\":\n // Base64-encoded binary payload — represented as a plain string in JTD.\n return { type: \"string\" };\n case undefined:\n default:\n return objectReflectionToJtd(reflection);\n }\n }\n\n case ReflectionKind.symbol:\n case ReflectionKind.property:\n case ReflectionKind.method:\n case ReflectionKind.function:\n case ReflectionKind.parameter:\n case ReflectionKind.typeParameter:\n case ReflectionKind.tupleMember:\n case ReflectionKind.enumMember:\n case ReflectionKind.rest:\n case ReflectionKind.indexSignature:\n case ReflectionKind.propertySignature:\n case ReflectionKind.methodSignature:\n case ReflectionKind.infer:\n case ReflectionKind.callSignature:\n default:\n return undefined;\n }\n}\n\n/**\n * Tests whether a JTD form is an enum form.\n *\n * @param form - The JTD form to inspect.\n * @returns `true` if the form is a JTD enum form.\n */\nfunction isEnumForm(\n form: SomeJTDSchemaType\n): form is { enum: string[]; nullable?: boolean } {\n return Array.isArray((form as { enum?: unknown[] }).enum);\n}\n\n/**\n * Tests whether a JTD form is a properties form (object).\n *\n * @param form - The JTD form to inspect.\n * @returns `true` if the form is a JTD properties form.\n */\nfunction isPropertiesForm(form: SomeJTDSchemaType): boolean {\n return (\n \"properties\" in (form as object) || \"optionalProperties\" in (form as object)\n );\n}\n\n/**\n * Tests whether a JTD form is the empty `{ nullable: true }` placeholder.\n *\n * @param form - The JTD form to inspect.\n * @returns `true` if the form has no shape constraints beyond `nullable`.\n */\nfunction isPureNullable(form: SomeJTDSchemaType): boolean {\n const keys = Object.keys(form as object).filter(\n k => k !== \"nullable\" && k !== \"metadata\"\n );\n\n return (\n keys.length === 0 && (form as { nullable?: boolean }).nullable === true\n );\n}\n\n/**\n * Shallow-merges two JTD properties forms, unioning their `properties` and `optionalProperties` maps.\n *\n * @param forms - The JTD properties forms to merge.\n * @returns The merged JTD properties form.\n */\nfunction mergePropertiesForms(forms: SomeJTDSchemaType[]): SomeJTDSchemaType {\n const merged: {\n properties: Record<string, SomeJTDSchemaType>;\n optionalProperties: Record<string, SomeJTDSchemaType>;\n additionalProperties?: boolean;\n } = {\n properties: {},\n optionalProperties: {}\n };\n for (const form of forms) {\n const p = (form as { properties?: Record<string, SomeJTDSchemaType> })\n .properties;\n const o = (\n form as { optionalProperties?: Record<string, SomeJTDSchemaType> }\n ).optionalProperties;\n if (p) {\n Object.assign(merged.properties, p);\n }\n if (o) {\n Object.assign(merged.optionalProperties, o);\n }\n if ((form as { additionalProperties?: boolean }).additionalProperties) {\n merged.additionalProperties = true;\n }\n }\n const hasProperties = Object.keys(merged.properties).length > 0;\n const hasOptional = Object.keys(merged.optionalProperties).length > 0;\n const result: SomeJTDSchemaType = {};\n if (hasProperties) {\n (result as { properties: Record<string, SomeJTDSchemaType> }).properties =\n merged.properties;\n } else if (!hasOptional) {\n (result as { properties: Record<string, SomeJTDSchemaType> }).properties =\n {};\n }\n if (hasOptional) {\n (\n result as { optionalProperties: Record<string, SomeJTDSchemaType> }\n ).optionalProperties = merged.optionalProperties;\n }\n if (merged.additionalProperties) {\n (result as { additionalProperties: boolean }).additionalProperties = true;\n }\n return result;\n}\n\n/**\n * Detects whether a Deepkit union represents a tagged union and, when so, emits the corresponding JTD discriminator form.\n *\n * @param types - The Deepkit reflection types that make up the union branches.\n * @returns A JTD discriminator form if every non-null branch is an object literal that shares a string-literal tag property, otherwise `undefined`.\n */\nfunction tryReflectionDiscriminator(\n types: readonly Type[]\n): SomeJTDSchemaType | undefined {\n const nonNullTypes = types.filter(\n t => t.kind !== ReflectionKind.null && t.kind !== ReflectionKind.undefined\n );\n const objectBranches: Array<TypeObjectLiteral | TypeClass> =\n nonNullTypes.filter(\n t =>\n t.kind === ReflectionKind.objectLiteral ||\n t.kind === ReflectionKind.class\n );\n if (\n objectBranches.length < 2 ||\n objectBranches.length !== nonNullTypes.length\n ) {\n return undefined;\n }\n\n let tagKey: string | undefined;\n const mapping: Record<string, SomeJTDSchemaType> = {};\n\n for (const branch of objectBranches) {\n const literalProps: Array<{ name: string; literal: string }> = [];\n for (const member of branch.types) {\n if (\n (member.kind === ReflectionKind.property ||\n member.kind === ReflectionKind.propertySignature) &&\n typeof member.name === \"string\" &&\n member.type.kind === ReflectionKind.literal &&\n typeof (member.type as { literal?: unknown }).literal === \"string\"\n ) {\n literalProps.push({\n name: member.name,\n literal: (member.type as { literal: string }).literal\n });\n }\n }\n if (literalProps.length === 0) {\n return undefined;\n }\n const first = literalProps[0]!;\n if (!tagKey) {\n tagKey = first.name;\n } else if (tagKey !== first.name) {\n return undefined;\n }\n\n // Build the branch body excluding the discriminator property.\n const filteredBranch = {\n ...branch,\n types: branch.types.filter(\n member =>\n !(\n (member.kind === ReflectionKind.property ||\n member.kind === ReflectionKind.propertySignature) &&\n member.name === tagKey\n )\n )\n } as TypeObjectLiteral | TypeClass;\n const body = objectReflectionToJtd(filteredBranch);\n if (!body || !isPropertiesForm(body)) {\n return undefined;\n }\n mapping[first.literal] = body;\n }\n\n if (!tagKey) {\n return undefined;\n }\n return { discriminator: tagKey, mapping };\n}\n\n/**\n * Builds a JTD properties form from a Deepkit class or object literal type.\n *\n * @param type - The class or object literal type whose members should be serialized.\n * @returns A JTD properties form describing the type's members.\n */\nexport function objectReflectionToJsonSchema<\n T = unknown,\n D extends Record<string, unknown> = Record<string, unknown>\n>(type: TypeObjectLiteral | TypeClass): JTDSchemaType<T, D> {\n return objectReflectionToJtd(type) as JTDSchemaType<T, D>;\n}\n\n/**\n * Internal worker that produces a JTD properties form (or `values` form for index signatures alone) from a Deepkit object-like type.\n *\n * @param type - The class or object literal type whose members should be serialized.\n * @returns A JTD properties or values form describing the type's members.\n */\nfunction objectReflectionToJtd(\n type: TypeObjectLiteral | TypeClass\n): SomeJTDSchemaType {\n const properties: Record<string, SomeJTDSchemaType> = {};\n const optionalProperties: Record<string, SomeJTDSchemaType> = {};\n let indexValueSchema: SomeJTDSchemaType | undefined;\n const description =\n \"description\" in type && typeof type.description === \"string\"\n ? type.description\n : undefined;\n\n for (const member of type.types) {\n if (\n member.kind === ReflectionKind.property ||\n member.kind === ReflectionKind.propertySignature\n ) {\n if (typeof member.name !== \"string\") {\n continue;\n }\n const propertySchema = reflectionToJtd(member.type);\n if (!propertySchema) {\n continue;\n }\n if (typeof member.description === \"string\") {\n attachDescription(propertySchema, member.description);\n }\n if (member.optional) {\n optionalProperties[member.name] = propertySchema;\n } else {\n properties[member.name] = propertySchema;\n }\n } else if (member.kind === ReflectionKind.indexSignature) {\n const valueSchema = reflectionToJtd(member.type);\n if (valueSchema) {\n indexValueSchema = valueSchema;\n }\n }\n }\n\n const hasProperties = Object.keys(properties).length > 0;\n const hasOptional = Object.keys(optionalProperties).length > 0;\n\n // Open map with no declared properties → JTD values form.\n if (!hasProperties && !hasOptional && indexValueSchema) {\n return attachDescription({ values: indexValueSchema }, description);\n }\n\n const form: {\n properties?: Record<string, SomeJTDSchemaType>;\n optionalProperties?: Record<string, SomeJTDSchemaType>;\n additionalProperties?: boolean;\n } = {};\n if (hasProperties) {\n form.properties = properties;\n } else if (!hasOptional) {\n form.properties = {};\n }\n if (hasOptional) {\n form.optionalProperties = optionalProperties;\n }\n if (indexValueSchema) {\n form.additionalProperties = true;\n }\n return attachDescription(form as SomeJTDSchemaType, description);\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { BundleOptions } from "./bundle.cjs";
2
- import { PluginContext } from "@powerlines/core";
2
+ import { TypeDefinitionReference } from "./types.cjs";
3
+ import { PluginContext, UnresolvedContext } from "@powerlines/core";
3
4
  import { Type } from "@powerlines/deepkit/vendor/type";
4
- import { TypeDefinitionParameter } from "@stryke/types/configuration";
5
5
 
6
6
  //#region src/resolve.d.ts
7
7
  /**
@@ -12,7 +12,7 @@ import { TypeDefinitionParameter } from "@stryke/types/configuration";
12
12
  * @param overrides - Optional overrides for the ESBuild configuration.
13
13
  * @returns A promise that resolves to the compiled module.
14
14
  */
15
- declare function resolveModule<TResult, TContext extends PluginContext = PluginContext>(context: TContext, type: TypeDefinitionParameter, overrides?: BundleOptions): Promise<TResult>;
15
+ declare function resolveModule<TResult, TContext extends UnresolvedContext = UnresolvedContext>(context: TContext, type: TypeDefinitionReference, overrides?: BundleOptions): Promise<TResult>;
16
16
  /**
17
17
  * Compiles a type definition to a module and returns the specified export from the module.
18
18
  *
@@ -21,7 +21,7 @@ declare function resolveModule<TResult, TContext extends PluginContext = PluginC
21
21
  * @param options - Optional overrides for the ESBuild configuration.
22
22
  * @returns A promise that resolves to the compiled module.
23
23
  */
24
- declare function resolve<TResult, TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionParameter, options?: BundleOptions): Promise<TResult>;
24
+ declare function resolve<TResult, TContext extends UnresolvedContext = UnresolvedContext>(context: TContext, input: TypeDefinitionReference, options?: BundleOptions): Promise<TResult>;
25
25
  /**
26
26
  * Resolves a type definition to a Deepkit Type reflection. This function compiles the provided type definition to a module, evaluates the module to get the specified export, and then reflects the export to get its Deepkit Type reflection.
27
27
  *
@@ -30,7 +30,7 @@ declare function resolve<TResult, TContext extends PluginContext = PluginContext
30
30
  * @param options - Optional overrides for the ESBuild configuration.
31
31
  * @returns A promise that resolves to the Deepkit Type reflection.
32
32
  */
33
- declare function resolveReflection<TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionParameter, options?: BundleOptions): Promise<Type>;
33
+ declare function resolveReflection<TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionReference, options?: BundleOptions): Promise<Type>;
34
34
  //#endregion
35
35
  export { resolve, resolveModule, resolveReflection };
36
36
  //# sourceMappingURL=resolve.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.cts","names":[],"sources":["../src/resolve.ts"],"mappings":";;;;;;;;AAuCA;;;;;;iBAAsB,aAAA,2BAEH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,IAAA,EAAM,uBAAA,EACN,SAAA,GAAY,aAAA,GACX,OAAA,CAAQ,OAAA;;;;;;;;;iBAyEW,OAAA,2BAEH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,OAAA;;;;;;;;;iBAiDW,iBAAA,kBACH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,IAAA"}
1
+ {"version":3,"file":"resolve.d.cts","names":[],"sources":["../src/resolve.ts"],"mappings":";;;;;;;;AAqCA;;;;;;iBAAsB,aAAA,2BAEH,iBAAA,GAAoB,iBAAA,CAAA,CAErC,OAAA,EAAS,QAAA,EACT,IAAA,EAAM,uBAAA,EACN,SAAA,GAAY,aAAA,GACX,OAAA,CAAQ,OAAA;;;;;;;;;iBAyEW,OAAA,2BAEH,iBAAA,GAAoB,iBAAA,CAAA,CAErC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,OAAA;;;;;;;;;iBAiDW,iBAAA,kBACH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,IAAA"}
@@ -1,7 +1,7 @@
1
1
  import { BundleOptions } from "./bundle.mjs";
2
- import { PluginContext } from "@powerlines/core";
2
+ import { TypeDefinitionReference } from "./types.mjs";
3
+ import { PluginContext, UnresolvedContext } from "@powerlines/core";
3
4
  import { Type } from "@powerlines/deepkit/vendor/type";
4
- import { TypeDefinitionParameter } from "@stryke/types/configuration";
5
5
 
6
6
  //#region src/resolve.d.ts
7
7
  /**
@@ -12,7 +12,7 @@ import { TypeDefinitionParameter } from "@stryke/types/configuration";
12
12
  * @param overrides - Optional overrides for the ESBuild configuration.
13
13
  * @returns A promise that resolves to the compiled module.
14
14
  */
15
- declare function resolveModule<TResult, TContext extends PluginContext = PluginContext>(context: TContext, type: TypeDefinitionParameter, overrides?: BundleOptions): Promise<TResult>;
15
+ declare function resolveModule<TResult, TContext extends UnresolvedContext = UnresolvedContext>(context: TContext, type: TypeDefinitionReference, overrides?: BundleOptions): Promise<TResult>;
16
16
  /**
17
17
  * Compiles a type definition to a module and returns the specified export from the module.
18
18
  *
@@ -21,7 +21,7 @@ declare function resolveModule<TResult, TContext extends PluginContext = PluginC
21
21
  * @param options - Optional overrides for the ESBuild configuration.
22
22
  * @returns A promise that resolves to the compiled module.
23
23
  */
24
- declare function resolve<TResult, TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionParameter, options?: BundleOptions): Promise<TResult>;
24
+ declare function resolve<TResult, TContext extends UnresolvedContext = UnresolvedContext>(context: TContext, input: TypeDefinitionReference, options?: BundleOptions): Promise<TResult>;
25
25
  /**
26
26
  * Resolves a type definition to a Deepkit Type reflection. This function compiles the provided type definition to a module, evaluates the module to get the specified export, and then reflects the export to get its Deepkit Type reflection.
27
27
  *
@@ -30,7 +30,7 @@ declare function resolve<TResult, TContext extends PluginContext = PluginContext
30
30
  * @param options - Optional overrides for the ESBuild configuration.
31
31
  * @returns A promise that resolves to the Deepkit Type reflection.
32
32
  */
33
- declare function resolveReflection<TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionParameter, options?: BundleOptions): Promise<Type>;
33
+ declare function resolveReflection<TContext extends PluginContext = PluginContext>(context: TContext, input: TypeDefinitionReference, options?: BundleOptions): Promise<Type>;
34
34
  //#endregion
35
35
  export { resolve, resolveModule, resolveReflection };
36
36
  //# sourceMappingURL=resolve.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.mts","names":[],"sources":["../src/resolve.ts"],"mappings":";;;;;;;;AAuCA;;;;;;iBAAsB,aAAA,2BAEH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,IAAA,EAAM,uBAAA,EACN,SAAA,GAAY,aAAA,GACX,OAAA,CAAQ,OAAA;;;;;;;;;iBAyEW,OAAA,2BAEH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,OAAA;;;;;;;;;iBAiDW,iBAAA,kBACH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,IAAA"}
1
+ {"version":3,"file":"resolve.d.mts","names":[],"sources":["../src/resolve.ts"],"mappings":";;;;;;;;AAqCA;;;;;;iBAAsB,aAAA,2BAEH,iBAAA,GAAoB,iBAAA,CAAA,CAErC,OAAA,EAAS,QAAA,EACT,IAAA,EAAM,uBAAA,EACN,SAAA,GAAY,aAAA,GACX,OAAA,CAAQ,OAAA;;;;;;;;;iBAyEW,OAAA,2BAEH,iBAAA,GAAoB,iBAAA,CAAA,CAErC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,OAAA;;;;;;;;;iBAiDW,iBAAA,kBACH,aAAA,GAAgB,aAAA,CAAA,CAEjC,OAAA,EAAS,QAAA,EACT,KAAA,EAAO,uBAAA,EACP,OAAA,GAAU,aAAA,GACT,OAAA,CAAQ,IAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.mjs","names":[],"sources":["../src/resolve.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { PluginContext } from \"@powerlines/core\";\nimport { esbuildPlugin } from \"@powerlines/deepkit/esbuild-plugin\";\nimport { reflect, Type } from \"@powerlines/deepkit/vendor/type\";\nimport { parseTypeDefinition } from \"@stryke/convert/parse-type-definition\";\nimport { findFileDotExtension } from \"@stryke/path/find\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport {\n TypeDefinition,\n TypeDefinitionParameter\n} from \"@stryke/types/configuration\";\nimport defu from \"defu\";\nimport { bundle, BundleOptions } from \"./bundle\";\n\n/**\n * Compiles a type definition to a module and returns the module.\n *\n * @param context - The context object containing the environment paths.\n * @param type - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param overrides - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the compiled module.\n */\nexport async function resolveModule<\n TResult,\n TContext extends PluginContext = PluginContext\n>(\n context: TContext,\n type: TypeDefinitionParameter,\n overrides?: BundleOptions\n): Promise<TResult> {\n let typeDefinition!: TypeDefinition;\n if (isSetString(type)) {\n typeDefinition = parseTypeDefinition(type) as TypeDefinition;\n } else {\n typeDefinition = type;\n }\n\n const result = await bundle<TContext>(\n context,\n typeDefinition.file,\n overrides\n );\n\n let resolved: any;\n try {\n resolved = await context.resolver.evalModule(result.text, {\n filename: result.path,\n ext: findFileDotExtension(result.path)\n });\n } catch (error) {\n if (\n isSetString((error as Error).message) &&\n new RegExp(\n `Cannot find module '${context.config.framework?.name || \"powerlines\"}:.*'`\n ).test((error as Error).message)\n ) {\n const moduleName = (error as Error).message.match(\n new RegExp(\n `Cannot find module '(${context.config.framework?.name || \"powerlines\"}:.*)'`\n )\n )?.[1];\n throw new Error(\n `The module \"${moduleName}\" could not be resolved while evaluating \"${\n typeDefinition.file\n }\". It is possible the required built-in modules have not yet been generated. Please check the order of your plugins. ${\n context.config.logLevel.general === \"debug\" ||\n context.config.logLevel.general === \"trace\"\n ? `\n\nBundle output for module:\n${result.text}`\n : \"\"\n }`\n );\n }\n\n throw new Error(\n `Failed to evaluate the bundled module for \"${\n typeDefinition.file\n }\". Error: ${(error as Error).message}${\n context.config.logLevel.general === \"debug\" ||\n context.config.logLevel.general === \"trace\"\n ? `\n\nBundle output for module:\n${result.text}`\n : \"\"\n }`\n );\n }\n\n return resolved;\n}\n\n/**\n * Compiles a type definition to a module and returns the specified export from the module.\n *\n * @param context - The context object containing the environment paths.\n * @param input - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param options - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the compiled module.\n */\nexport async function resolve<\n TResult,\n TContext extends PluginContext = PluginContext\n>(\n context: TContext,\n input: TypeDefinitionParameter,\n options?: BundleOptions\n): Promise<TResult> {\n let typeDefinition!: TypeDefinition;\n if (isSetString(input)) {\n typeDefinition = parseTypeDefinition(input) as TypeDefinition;\n } else {\n typeDefinition = input;\n }\n\n const resolved = await resolveModule<Record<string, any>, TContext>(\n context,\n typeDefinition,\n options\n );\n\n let exportName = typeDefinition.name;\n if (!exportName) {\n exportName = \"default\";\n }\n\n const resolvedExport = resolved[exportName] ?? resolved[`__Ω${exportName}`];\n if (resolvedExport === undefined) {\n throw new Error(\n `The export \"${exportName}\" could not be resolved in the \"${\n typeDefinition.file\n }\" module. ${\n Object.keys(resolved).length === 0\n ? `After bundling, no exports were found in the module. Please ensure that the \"${\n typeDefinition.file\n }\" module has a \"${exportName}\" export with the desired value.`\n : `After bundling, the available exports were: ${Object.keys(\n resolved\n ).join(\n \", \"\n )}. Please ensure that the export exists and is correctly named.`\n }`\n );\n }\n\n return resolvedExport;\n}\n\n/**\n * Resolves a type definition to a Deepkit Type reflection. This function compiles the provided type definition to a module, evaluates the module to get the specified export, and then reflects the export to get its Deepkit Type reflection.\n *\n * @param context - The context object containing the environment paths.\n * @param input - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param options - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the Deepkit Type reflection.\n */\nexport async function resolveReflection<\n TContext extends PluginContext = PluginContext\n>(\n context: TContext,\n input: TypeDefinitionParameter,\n options?: BundleOptions\n): Promise<Type> {\n return reflect(\n await resolve<Type>(\n context,\n input,\n defu(options, {\n plugins: [\n esbuildPlugin(context, {\n reflection: \"default\",\n level: \"all\"\n })\n ]\n })\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAuCA,eAAsB,cAIpB,SACA,MACA,WACkB;CAClB,IAAI;AACJ,KAAI,YAAY,KAAK,CACnB,kBAAiB,oBAAoB,KAAK;KAE1C,kBAAiB;CAGnB,MAAM,SAAS,MAAM,OACnB,SACA,eAAe,MACf,UACD;CAED,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,SAAS,WAAW,OAAO,MAAM;GACxD,UAAU,OAAO;GACjB,KAAK,qBAAqB,OAAO,KAAK;GACvC,CAAC;UACK,OAAO;AACd,MACE,YAAa,MAAgB,QAAQ,IACrC,IAAI,OACF,uBAAuB,QAAQ,OAAO,WAAW,QAAQ,aAAa,MACvE,CAAC,KAAM,MAAgB,QAAQ,EAChC;GACA,MAAM,aAAc,MAAgB,QAAQ,MAC1C,IAAI,OACF,wBAAwB,QAAQ,OAAO,WAAW,QAAQ,aAAa,OACxE,CACF,GAAG;AACJ,SAAM,IAAI,MACR,eAAe,WAAW,4CACxB,eAAe,KAChB,uHACC,QAAQ,OAAO,SAAS,YAAY,WACpC,QAAQ,OAAO,SAAS,YAAY,UAChC;;;EAGZ,OAAO,SACK,KAEP;;AAGH,QAAM,IAAI,MACR,8CACE,eAAe,KAChB,YAAa,MAAgB,UAC5B,QAAQ,OAAO,SAAS,YAAY,WACpC,QAAQ,OAAO,SAAS,YAAY,UAChC;;;EAGV,OAAO,SACG,KAEP;;AAGH,QAAO;;;;;;;;;;AAWT,eAAsB,QAIpB,SACA,OACA,SACkB;CAClB,IAAI;AACJ,KAAI,YAAY,MAAM,CACpB,kBAAiB,oBAAoB,MAAM;KAE3C,kBAAiB;CAGnB,MAAM,WAAW,MAAM,cACrB,SACA,gBACA,QACD;CAED,IAAI,aAAa,eAAe;AAChC,KAAI,CAAC,WACH,cAAa;CAGf,MAAM,iBAAiB,SAAS,eAAe,SAAS,MAAM;AAC9D,KAAI,mBAAmB,OACrB,OAAM,IAAI,MACR,eAAe,WAAW,kCACxB,eAAe,KAChB,YACC,OAAO,KAAK,SAAS,CAAC,WAAW,IAC7B,gFACE,eAAe,KAChB,kBAAkB,WAAW,oCAC9B,+CAA+C,OAAO,KACpD,SACD,CAAC,KACA,KACD,CAAC,kEAET;AAGH,QAAO;;;;;;;;;;AAWT,eAAsB,kBAGpB,SACA,OACA,SACe;AACf,QAAO,QACL,MAAM,QACJ,SACA,OACA,KAAK,SAAS,EACZ,SAAS,CACP,cAAc,SAAS;EACrB,YAAY;EACZ,OAAO;EACR,CAAC,CACH,EACF,CAAC,CACH,CACF"}
1
+ {"version":3,"file":"resolve.mjs","names":[],"sources":["../src/resolve.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Powerlines\n\n This code was released as part of the Powerlines project. Powerlines\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/powerlines.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/powerlines\n Documentation: https://docs.stormsoftware.com/projects/powerlines\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { PluginContext, UnresolvedContext } from \"@powerlines/core\";\nimport { esbuildPlugin } from \"@powerlines/deepkit/esbuild-plugin\";\nimport { reflect, Type } from \"@powerlines/deepkit/vendor/type\";\nimport { parseTypeDefinition } from \"@stryke/convert/parse-type-definition\";\nimport { findFileDotExtension } from \"@stryke/path/find\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { TypeDefinition } from \"@stryke/types/configuration\";\nimport defu from \"defu\";\nimport { bundle, BundleOptions } from \"./bundle\";\nimport { TypeDefinitionReference } from \"./types\";\n\n/**\n * Compiles a type definition to a module and returns the module.\n *\n * @param context - The context object containing the environment paths.\n * @param type - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param overrides - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the compiled module.\n */\nexport async function resolveModule<\n TResult,\n TContext extends UnresolvedContext = UnresolvedContext\n>(\n context: TContext,\n type: TypeDefinitionReference,\n overrides?: BundleOptions\n): Promise<TResult> {\n let typeDefinition!: TypeDefinition;\n if (isSetString(type)) {\n typeDefinition = parseTypeDefinition(type) as TypeDefinition;\n } else {\n typeDefinition = type;\n }\n\n const result = await bundle<TContext>(\n context,\n typeDefinition.file,\n overrides\n );\n\n let resolved: any;\n try {\n resolved = await context.resolver.evalModule(result.text, {\n filename: result.path,\n ext: findFileDotExtension(result.path)\n });\n } catch (error) {\n if (\n isSetString((error as Error).message) &&\n new RegExp(\n `Cannot find module '${context.config.framework?.name || \"powerlines\"}:.*'`\n ).test((error as Error).message)\n ) {\n const moduleName = (error as Error).message.match(\n new RegExp(\n `Cannot find module '(${context.config.framework?.name || \"powerlines\"}:.*)'`\n )\n )?.[1];\n throw new Error(\n `The module \"${moduleName}\" could not be resolved while evaluating \"${\n typeDefinition.file\n }\". It is possible the required built-in modules have not yet been generated. Please check the order of your plugins. ${\n context.config.logLevel.general === \"debug\" ||\n context.config.logLevel.general === \"trace\"\n ? `\n\nBundle output for module:\n${result.text}`\n : \"\"\n }`\n );\n }\n\n throw new Error(\n `Failed to evaluate the bundled module for \"${\n typeDefinition.file\n }\". Error: ${(error as Error).message}${\n context.config.logLevel.general === \"debug\" ||\n context.config.logLevel.general === \"trace\"\n ? `\n\nBundle output for module:\n${result.text}`\n : \"\"\n }`\n );\n }\n\n return resolved;\n}\n\n/**\n * Compiles a type definition to a module and returns the specified export from the module.\n *\n * @param context - The context object containing the environment paths.\n * @param input - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param options - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the compiled module.\n */\nexport async function resolve<\n TResult,\n TContext extends UnresolvedContext = UnresolvedContext\n>(\n context: TContext,\n input: TypeDefinitionReference,\n options?: BundleOptions\n): Promise<TResult> {\n let typeDefinition!: TypeDefinition;\n if (isSetString(input)) {\n typeDefinition = parseTypeDefinition(input) as TypeDefinition;\n } else {\n typeDefinition = input;\n }\n\n const resolved = await resolveModule<Record<string, any>, TContext>(\n context,\n typeDefinition,\n options\n );\n\n let exportName = typeDefinition.name;\n if (!exportName) {\n exportName = \"default\";\n }\n\n const resolvedExport = resolved[exportName] ?? resolved[`__Ω${exportName}`];\n if (resolvedExport === undefined) {\n throw new Error(\n `The export \"${exportName}\" could not be resolved in the \"${\n typeDefinition.file\n }\" module. ${\n Object.keys(resolved).length === 0\n ? `After bundling, no exports were found in the module. Please ensure that the \"${\n typeDefinition.file\n }\" module has a \"${exportName}\" export with the desired value.`\n : `After bundling, the available exports were: ${Object.keys(\n resolved\n ).join(\n \", \"\n )}. Please ensure that the export exists and is correctly named.`\n }`\n );\n }\n\n return resolvedExport;\n}\n\n/**\n * Resolves a type definition to a Deepkit Type reflection. This function compiles the provided type definition to a module, evaluates the module to get the specified export, and then reflects the export to get its Deepkit Type reflection.\n *\n * @param context - The context object containing the environment paths.\n * @param input - The type definition to compile. This can be either a string or a {@link TypeDefinition} object.\n * @param options - Optional overrides for the ESBuild configuration.\n * @returns A promise that resolves to the Deepkit Type reflection.\n */\nexport async function resolveReflection<\n TContext extends PluginContext = PluginContext\n>(\n context: TContext,\n input: TypeDefinitionReference,\n options?: BundleOptions\n): Promise<Type> {\n return reflect(\n await resolve<Type>(\n context,\n input,\n defu(options, {\n plugins: [\n esbuildPlugin(context, {\n reflection: \"default\",\n level: \"all\"\n })\n ]\n })\n )\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqCA,eAAsB,cAIpB,SACA,MACA,WACkB;CAClB,IAAI;AACJ,KAAI,YAAY,KAAK,CACnB,kBAAiB,oBAAoB,KAAK;KAE1C,kBAAiB;CAGnB,MAAM,SAAS,MAAM,OACnB,SACA,eAAe,MACf,UACD;CAED,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,SAAS,WAAW,OAAO,MAAM;GACxD,UAAU,OAAO;GACjB,KAAK,qBAAqB,OAAO,KAAK;GACvC,CAAC;UACK,OAAO;AACd,MACE,YAAa,MAAgB,QAAQ,IACrC,IAAI,OACF,uBAAuB,QAAQ,OAAO,WAAW,QAAQ,aAAa,MACvE,CAAC,KAAM,MAAgB,QAAQ,EAChC;GACA,MAAM,aAAc,MAAgB,QAAQ,MAC1C,IAAI,OACF,wBAAwB,QAAQ,OAAO,WAAW,QAAQ,aAAa,OACxE,CACF,GAAG;AACJ,SAAM,IAAI,MACR,eAAe,WAAW,4CACxB,eAAe,KAChB,uHACC,QAAQ,OAAO,SAAS,YAAY,WACpC,QAAQ,OAAO,SAAS,YAAY,UAChC;;;EAGZ,OAAO,SACK,KAEP;;AAGH,QAAM,IAAI,MACR,8CACE,eAAe,KAChB,YAAa,MAAgB,UAC5B,QAAQ,OAAO,SAAS,YAAY,WACpC,QAAQ,OAAO,SAAS,YAAY,UAChC;;;EAGV,OAAO,SACG,KAEP;;AAGH,QAAO;;;;;;;;;;AAWT,eAAsB,QAIpB,SACA,OACA,SACkB;CAClB,IAAI;AACJ,KAAI,YAAY,MAAM,CACpB,kBAAiB,oBAAoB,MAAM;KAE3C,kBAAiB;CAGnB,MAAM,WAAW,MAAM,cACrB,SACA,gBACA,QACD;CAED,IAAI,aAAa,eAAe;AAChC,KAAI,CAAC,WACH,cAAa;CAGf,MAAM,iBAAiB,SAAS,eAAe,SAAS,MAAM;AAC9D,KAAI,mBAAmB,OACrB,OAAM,IAAI,MACR,eAAe,WAAW,kCACxB,eAAe,KAChB,YACC,OAAO,KAAK,SAAS,CAAC,WAAW,IAC7B,gFACE,eAAe,KAChB,kBAAkB,WAAW,oCAC9B,+CAA+C,OAAO,KACpD,SACD,CAAC,KACA,KACD,CAAC,kEAET;AAGH,QAAO;;;;;;;;;;AAWT,eAAsB,kBAGpB,SACA,OACA,SACe;AACf,QAAO,QACL,MAAM,QACJ,SACA,OACA,KAAK,SAAS,EACZ,SAAS,CACP,cAAc,SAAS;EACrB,YAAY;EACZ,OAAO;EACR,CAAC,CACH,EACF,CAAC,CACH,CACF"}