@kubb/ast 5.0.0-beta.6 → 5.0.0-beta.61

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 (102) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +51 -27
  3. package/dist/chunk-CNktS9qV.js +17 -0
  4. package/dist/defineMacro-BLIR6k-j.d.ts +475 -0
  5. package/dist/defineMacro-BTXvS8nI.js +106 -0
  6. package/dist/defineMacro-BTXvS8nI.js.map +1 -0
  7. package/dist/defineMacro-Bv9R_9a2.cjs +123 -0
  8. package/dist/defineMacro-Bv9R_9a2.cjs.map +1 -0
  9. package/dist/extractStringsFromNodes-Cja-xxx5.js +29 -0
  10. package/dist/extractStringsFromNodes-Cja-xxx5.js.map +1 -0
  11. package/dist/extractStringsFromNodes-DKgDjFO0.cjs +34 -0
  12. package/dist/extractStringsFromNodes-DKgDjFO0.cjs.map +1 -0
  13. package/dist/extractStringsFromNodes-p4mX1TQD.d.ts +14 -0
  14. package/dist/factory-CZNOGI-N.js +283 -0
  15. package/dist/factory-CZNOGI-N.js.map +1 -0
  16. package/dist/factory-DG1CVkEb.cjs +300 -0
  17. package/dist/factory-DG1CVkEb.cjs.map +1 -0
  18. package/dist/factory.cjs +29 -0
  19. package/dist/factory.d.ts +62 -0
  20. package/dist/factory.js +3 -0
  21. package/dist/index-BzjwdK2M.d.ts +2433 -0
  22. package/dist/index.cjs +444 -2180
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +94 -3408
  25. package/dist/index.js +395 -2101
  26. package/dist/index.js.map +1 -1
  27. package/dist/macros.cjs +117 -0
  28. package/dist/macros.cjs.map +1 -0
  29. package/dist/macros.d.ts +59 -0
  30. package/dist/macros.js +115 -0
  31. package/dist/macros.js.map +1 -0
  32. package/dist/operationParams-BZ07xDm0.d.ts +204 -0
  33. package/dist/response-KUdWiDWw.js +658 -0
  34. package/dist/response-KUdWiDWw.js.map +1 -0
  35. package/dist/response-hnSw2NKE.cjs +1027 -0
  36. package/dist/response-hnSw2NKE.cjs.map +1 -0
  37. package/dist/types-DyDzizSf.d.ts +364 -0
  38. package/dist/types.cjs +0 -0
  39. package/dist/types.d.ts +6 -0
  40. package/dist/types.js +1 -0
  41. package/dist/utils-BLJwyza-.cjs +912 -0
  42. package/dist/utils-BLJwyza-.cjs.map +1 -0
  43. package/dist/utils-CF_-Pn_c.js +770 -0
  44. package/dist/utils-CF_-Pn_c.js.map +1 -0
  45. package/dist/utils.cjs +36 -0
  46. package/dist/utils.d.ts +358 -0
  47. package/dist/utils.js +4 -0
  48. package/dist/visitor-DJ6ZEJvq.js +548 -0
  49. package/dist/visitor-DJ6ZEJvq.js.map +1 -0
  50. package/dist/visitor-DpKZ9Tk0.cjs +654 -0
  51. package/dist/visitor-DpKZ9Tk0.cjs.map +1 -0
  52. package/package.json +21 -6
  53. package/src/constants.ts +19 -64
  54. package/src/dedupe.ts +239 -0
  55. package/src/defineMacro.ts +132 -0
  56. package/src/dialect.ts +53 -0
  57. package/src/factory.ts +67 -678
  58. package/src/guards.ts +10 -92
  59. package/src/index.ts +13 -44
  60. package/src/infer.ts +16 -14
  61. package/src/macros/index.ts +3 -0
  62. package/src/macros/macroDiscriminatorEnum.ts +44 -0
  63. package/src/macros/macroEnumName.ts +25 -0
  64. package/src/macros/macroSimplifyUnion.ts +50 -0
  65. package/src/mocks.ts +7 -127
  66. package/src/node.ts +128 -0
  67. package/src/nodes/base.ts +5 -12
  68. package/src/nodes/code.ts +165 -74
  69. package/src/nodes/content.ts +56 -0
  70. package/src/nodes/file.ts +97 -36
  71. package/src/nodes/function.ts +216 -156
  72. package/src/nodes/http.ts +1 -35
  73. package/src/nodes/index.ts +23 -15
  74. package/src/nodes/input.ts +140 -0
  75. package/src/nodes/operation.ts +122 -68
  76. package/src/nodes/output.ts +23 -0
  77. package/src/nodes/parameter.ts +33 -3
  78. package/src/nodes/property.ts +36 -3
  79. package/src/nodes/requestBody.ts +61 -0
  80. package/src/nodes/response.ts +58 -13
  81. package/src/nodes/schema.ts +93 -17
  82. package/src/printer.ts +48 -42
  83. package/src/registry.ts +75 -0
  84. package/src/signature.ts +207 -0
  85. package/src/types.ts +8 -68
  86. package/src/utils/codegen.ts +104 -0
  87. package/src/utils/extractStringsFromNodes.ts +34 -0
  88. package/src/utils/fileMerge.ts +184 -0
  89. package/src/utils/index.ts +11 -0
  90. package/src/utils/operationParams.ts +353 -0
  91. package/src/utils/refs.ts +138 -0
  92. package/src/utils/schemaGraph.ts +169 -0
  93. package/src/utils/schemaMerge.ts +34 -0
  94. package/src/utils/schemaTraversal.ts +86 -0
  95. package/src/utils/strings.ts +139 -0
  96. package/src/visitor.ts +227 -289
  97. package/dist/chunk--u3MIqq1.js +0 -8
  98. package/src/nodes/root.ts +0 -64
  99. package/src/refs.ts +0 -67
  100. package/src/resolvers.ts +0 -45
  101. package/src/transformers.ts +0 -159
  102. package/src/utils.ts +0 -915
@@ -0,0 +1,86 @@
1
+ import type { ArraySchemaNode, IntersectionSchemaNode, ObjectSchemaNode, PropertyNode, SchemaNode, UnionSchemaNode } from '../nodes/index.ts'
2
+ import { objectKey } from './codegen.ts'
3
+
4
+ /**
5
+ * Converts a child schema to printer output. Plugins instantiate it with their own output type:
6
+ * `string` for the zod and faker printers, `ts.TypeNode` for the TypeScript printer. A printer's
7
+ * `this.transform` fits directly, so its `null` for an empty result carries through to `output`.
8
+ */
9
+ export type SchemaTransform<TOutput> = (schema: SchemaNode) => TOutput
10
+
11
+ /**
12
+ * A union or intersection member, or an array or tuple item, paired with its transformed output.
13
+ */
14
+ export type MappedSchema<TOutput> = {
15
+ /**
16
+ * The original child schema, kept so the printer can read its metadata for leaf formatting.
17
+ */
18
+ schema: SchemaNode
19
+ /**
20
+ * The child schema after being run through the transform.
21
+ */
22
+ output: TOutput
23
+ }
24
+
25
+ /**
26
+ * An object property paired with its transformed output.
27
+ */
28
+ export type MappedProperty<TOutput> = {
29
+ /**
30
+ * The property name as written on the schema, before any identifier quoting.
31
+ */
32
+ name: string
33
+ /**
34
+ * The original property node, kept so the printer can read `required`, `schema`, and metadata.
35
+ */
36
+ property: PropertyNode
37
+ /**
38
+ * The property schema after being run through the transform.
39
+ */
40
+ output: TOutput
41
+ }
42
+
43
+ /**
44
+ * Maps each property of an object schema to its transformed output. Pairs every result with the
45
+ * original property so the printer keeps full control over modifiers, getters, and key syntax.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const entries = mapSchemaProperties(node, (schema) => this.transform(schema))
50
+ * // entries: [{ name: 'id', property, output: 'z.number()' }, ...]
51
+ * ```
52
+ */
53
+ export function mapSchemaProperties<TOutput>(node: ObjectSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedProperty<TOutput>> {
54
+ return node.properties.map((property) => ({ name: property.name, property, output: transform(property.schema) }))
55
+ }
56
+
57
+ /**
58
+ * Maps each member of a union or intersection schema to its transformed output, pairing every
59
+ * result with the original member.
60
+ */
61
+ export function mapSchemaMembers<TOutput>(node: UnionSchemaNode | IntersectionSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {
62
+ return (node.members ?? []).map((schema) => ({ schema, output: transform(schema) }))
63
+ }
64
+
65
+ /**
66
+ * Maps each item of an array or tuple schema to its transformed output, pairing every result with
67
+ * the original item.
68
+ */
69
+ export function mapSchemaItems<TOutput>(node: ArraySchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {
70
+ return (node.items ?? []).map((schema) => ({ schema, output: transform(schema) }))
71
+ }
72
+
73
+ /**
74
+ * Emits a lazy getter for a circular-ref property position, `get name() { return body }`. The key
75
+ * is quoted only when it is not a valid identifier. Used by the string printers to defer evaluation
76
+ * of a recursive schema until first access.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * lazyGetter({ name: 'parent', body: 'z.lazy(() => Pet)' })
81
+ * // "get parent() { return z.lazy(() => Pet) }"
82
+ * ```
83
+ */
84
+ export function lazyGetter({ name, body }: { name: string; body: string }): string {
85
+ return `get ${objectKey(name)}() { return ${body} }`
86
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
3
+ * Returns the string unchanged when no balanced quote pair is found.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * trimQuotes('"hello"') // 'hello'
8
+ * trimQuotes('hello') // 'hello'
9
+ * ```
10
+ */
11
+ export function trimQuotes(text: string): string {
12
+ if (text.length >= 2) {
13
+ const first = text[0]
14
+ const last = text[text.length - 1]
15
+ if ((first === '"' && last === '"') || (first === "'" && last === "'") || (first === '`' && last === '`')) {
16
+ return text.slice(1, -1)
17
+ }
18
+ }
19
+ return text
20
+ }
21
+
22
+ /**
23
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
24
+ *
25
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
26
+ * code matches the repo style without a formatter.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * stringify('hello') // "'hello'"
31
+ * stringify('"hello"') // "'hello'"
32
+ * ```
33
+ */
34
+ export function stringify(value: string | number | boolean | undefined): string {
35
+ if (value === undefined || value === null) return "''"
36
+ const json = JSON.stringify(trimQuotes(value.toString()))
37
+ const inner = json.slice(1, -1).replace(/\\"/g, '"').replace(/'/g, "\\'")
38
+ return `'${inner}'`
39
+ }
40
+
41
+ /**
42
+ * Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
43
+ * and the Unicode line terminators U+2028 and U+2029.
44
+ *
45
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
50
+ * ```
51
+ */
52
+ export function jsStringEscape(input: unknown): string {
53
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
54
+ switch (character) {
55
+ case '"':
56
+ case "'":
57
+ case '\\':
58
+ return `\\${character}`
59
+ case '\n':
60
+ return '\\n'
61
+ case '\r':
62
+ return '\\r'
63
+ case '\u2028':
64
+ return '\\u2028'
65
+ case '\u2029':
66
+ return '\\u2029'
67
+ default:
68
+ return ''
69
+ }
70
+ })
71
+ }
72
+
73
+ /**
74
+ * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
75
+ * Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
76
+ * Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
81
+ * toRegExpString('^(?im)foo', null) // '/^foo/im'
82
+ * ```
83
+ */
84
+ export function toRegExpString(text: string, func: string | null = 'RegExp'): string {
85
+ const raw = trimQuotes(text)
86
+
87
+ const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i)
88
+ const replacementTarget = match?.[1] ?? ''
89
+ const matchedFlags = match?.[2]
90
+ const cleaned = raw
91
+ .replace(/^\\?\//, '')
92
+ .replace(/\\?\/$/, '')
93
+ .replace(replacementTarget, '')
94
+
95
+ const { source, flags } = new RegExp(cleaned, matchedFlags)
96
+
97
+ if (func === null) return `/${source}/${flags}`
98
+
99
+ return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ''})`
100
+ }
101
+
102
+ /**
103
+ * Renders a plain object as multi-line `key: value` source for embedding in generated code. Nested
104
+ * objects recurse with fixed indentation, so the result drops straight into an object literal
105
+ * without re-parsing.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * stringifyObject({ foo: 'bar', nested: { a: 1 } })
110
+ * // 'foo: bar,\nnested: {\n a: 1\n }'
111
+ * ```
112
+ */
113
+ export function stringifyObject(value: Record<string, unknown>): string {
114
+ const items = Object.entries(value)
115
+ .map(([key, val]) => {
116
+ if (val !== null && typeof val === 'object') {
117
+ return `${key}: {\n ${stringifyObject(val as Record<string, unknown>)}\n }`
118
+ }
119
+ return `${key}: ${val}`
120
+ })
121
+ .filter(Boolean)
122
+ return items.join(',\n')
123
+ }
124
+
125
+ /**
126
+ * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
127
+ * `accessor`. Returns `null` for an empty path.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * getNestedAccessor('pagination.next.id', 'lastPage')
132
+ * // "lastPage?.['pagination']?.['next']?.['id']"
133
+ * ```
134
+ */
135
+ export function getNestedAccessor(param: string | Array<string>, accessor: string): string | null {
136
+ const parts = Array.isArray(param) ? param : param.split('.')
137
+ if (parts.length === 0 || (parts.length === 1 && parts[0] === '')) return null
138
+ return `${accessor}?.['${`${parts.join("']?.['")}']`}`
139
+ }