@redocly/client-generator 0.0.0-snapshot.1784554531
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +506 -0
- package/lib/config-file.d.ts +8 -0
- package/lib/config-file.d.ts.map +1 -0
- package/lib/config-file.js +32 -0
- package/lib/config-file.js.map +1 -0
- package/lib/config.d.ts +63 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +2 -0
- package/lib/config.js.map +1 -0
- package/lib/emitters/auth.d.ts +14 -0
- package/lib/emitters/auth.d.ts.map +1 -0
- package/lib/emitters/auth.js +30 -0
- package/lib/emitters/auth.js.map +1 -0
- package/lib/emitters/client-assembly.d.ts +15 -0
- package/lib/emitters/client-assembly.d.ts.map +1 -0
- package/lib/emitters/client-assembly.js +299 -0
- package/lib/emitters/client-assembly.js.map +1 -0
- package/lib/emitters/descriptor.d.ts +22 -0
- package/lib/emitters/descriptor.d.ts.map +1 -0
- package/lib/emitters/descriptor.js +207 -0
- package/lib/emitters/descriptor.js.map +1 -0
- package/lib/emitters/emit-options.d.ts +71 -0
- package/lib/emitters/emit-options.d.ts.map +1 -0
- package/lib/emitters/emit-options.js +28 -0
- package/lib/emitters/emit-options.js.map +1 -0
- package/lib/emitters/faker.d.ts +11 -0
- package/lib/emitters/faker.d.ts.map +1 -0
- package/lib/emitters/faker.js +204 -0
- package/lib/emitters/faker.js.map +1 -0
- package/lib/emitters/identifier.d.ts +28 -0
- package/lib/emitters/identifier.d.ts.map +1 -0
- package/lib/emitters/identifier.js +94 -0
- package/lib/emitters/identifier.js.map +1 -0
- package/lib/emitters/inline-runtime.d.ts +11 -0
- package/lib/emitters/inline-runtime.d.ts.map +1 -0
- package/lib/emitters/inline-runtime.js +97 -0
- package/lib/emitters/inline-runtime.js.map +1 -0
- package/lib/emitters/jsdoc.d.ts +9 -0
- package/lib/emitters/jsdoc.d.ts.map +1 -0
- package/lib/emitters/jsdoc.js +83 -0
- package/lib/emitters/jsdoc.js.map +1 -0
- package/lib/emitters/mock.d.ts +22 -0
- package/lib/emitters/mock.d.ts.map +1 -0
- package/lib/emitters/mock.js +243 -0
- package/lib/emitters/mock.js.map +1 -0
- package/lib/emitters/operation-aliases.d.ts +27 -0
- package/lib/emitters/operation-aliases.d.ts.map +1 -0
- package/lib/emitters/operation-aliases.js +138 -0
- package/lib/emitters/operation-aliases.js.map +1 -0
- package/lib/emitters/operation-signature.d.ts +23 -0
- package/lib/emitters/operation-signature.d.ts.map +1 -0
- package/lib/emitters/operation-signature.js +34 -0
- package/lib/emitters/operation-signature.js.map +1 -0
- package/lib/emitters/operation-types.d.ts +32 -0
- package/lib/emitters/operation-types.d.ts.map +1 -0
- package/lib/emitters/operation-types.js +117 -0
- package/lib/emitters/operation-types.js.map +1 -0
- package/lib/emitters/operations.d.ts +39 -0
- package/lib/emitters/operations.d.ts.map +1 -0
- package/lib/emitters/operations.js +33 -0
- package/lib/emitters/operations.js.map +1 -0
- package/lib/emitters/pagination.d.ts +69 -0
- package/lib/emitters/pagination.d.ts.map +1 -0
- package/lib/emitters/pagination.js +223 -0
- package/lib/emitters/pagination.js.map +1 -0
- package/lib/emitters/runtime-sources.d.ts +16 -0
- package/lib/emitters/runtime-sources.d.ts.map +1 -0
- package/lib/emitters/runtime-sources.js +16 -0
- package/lib/emitters/runtime-sources.js.map +1 -0
- package/lib/emitters/sample.d.ts +27 -0
- package/lib/emitters/sample.d.ts.map +1 -0
- package/lib/emitters/sample.js +161 -0
- package/lib/emitters/sample.js.map +1 -0
- package/lib/emitters/setup-bake.d.ts +15 -0
- package/lib/emitters/setup-bake.d.ts.map +1 -0
- package/lib/emitters/setup-bake.js +65 -0
- package/lib/emitters/setup-bake.js.map +1 -0
- package/lib/emitters/sse.d.ts +10 -0
- package/lib/emitters/sse.d.ts.map +1 -0
- package/lib/emitters/sse.js +46 -0
- package/lib/emitters/sse.js.map +1 -0
- package/lib/emitters/support.d.ts +13 -0
- package/lib/emitters/support.d.ts.map +1 -0
- package/lib/emitters/support.js +21 -0
- package/lib/emitters/support.js.map +1 -0
- package/lib/emitters/swr.d.ts +10 -0
- package/lib/emitters/swr.d.ts.map +1 -0
- package/lib/emitters/swr.js +88 -0
- package/lib/emitters/swr.js.map +1 -0
- package/lib/emitters/tanstack-query.d.ts +11 -0
- package/lib/emitters/tanstack-query.d.ts.map +1 -0
- package/lib/emitters/tanstack-query.js +68 -0
- package/lib/emitters/tanstack-query.js.map +1 -0
- package/lib/emitters/transformers.d.ts +11 -0
- package/lib/emitters/transformers.d.ts.map +1 -0
- package/lib/emitters/transformers.js +334 -0
- package/lib/emitters/transformers.js.map +1 -0
- package/lib/emitters/ts.d.ts +40 -0
- package/lib/emitters/ts.d.ts.map +1 -0
- package/lib/emitters/ts.js +104 -0
- package/lib/emitters/ts.js.map +1 -0
- package/lib/emitters/type-guards.d.ts +21 -0
- package/lib/emitters/type-guards.d.ts.map +1 -0
- package/lib/emitters/type-guards.js +183 -0
- package/lib/emitters/type-guards.js.map +1 -0
- package/lib/emitters/types.d.ts +23 -0
- package/lib/emitters/types.d.ts.map +1 -0
- package/lib/emitters/types.js +127 -0
- package/lib/emitters/types.js.map +1 -0
- package/lib/emitters/wrapper-support.d.ts +40 -0
- package/lib/emitters/wrapper-support.d.ts.map +1 -0
- package/lib/emitters/wrapper-support.js +112 -0
- package/lib/emitters/wrapper-support.js.map +1 -0
- package/lib/emitters/zod.d.ts +13 -0
- package/lib/emitters/zod.d.ts.map +1 -0
- package/lib/emitters/zod.js +344 -0
- package/lib/emitters/zod.js.map +1 -0
- package/lib/errors.d.ts +4 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +7 -0
- package/lib/errors.js.map +1 -0
- package/lib/generators/anchor.d.ts +9 -0
- package/lib/generators/anchor.d.ts.map +1 -0
- package/lib/generators/anchor.js +10 -0
- package/lib/generators/anchor.js.map +1 -0
- package/lib/generators/index.d.ts +15 -0
- package/lib/generators/index.d.ts.map +1 -0
- package/lib/generators/index.js +62 -0
- package/lib/generators/index.js.map +1 -0
- package/lib/generators/mock.d.ts +9 -0
- package/lib/generators/mock.d.ts.map +1 -0
- package/lib/generators/mock.js +23 -0
- package/lib/generators/mock.js.map +1 -0
- package/lib/generators/resolve.d.ts +19 -0
- package/lib/generators/resolve.d.ts.map +1 -0
- package/lib/generators/resolve.js +68 -0
- package/lib/generators/resolve.js.map +1 -0
- package/lib/generators/sdk.d.ts +12 -0
- package/lib/generators/sdk.d.ts.map +1 -0
- package/lib/generators/sdk.js +26 -0
- package/lib/generators/sdk.js.map +1 -0
- package/lib/generators/swr.d.ts +15 -0
- package/lib/generators/swr.d.ts.map +1 -0
- package/lib/generators/swr.js +27 -0
- package/lib/generators/swr.js.map +1 -0
- package/lib/generators/tanstack-query.d.ts +17 -0
- package/lib/generators/tanstack-query.d.ts.map +1 -0
- package/lib/generators/tanstack-query.js +30 -0
- package/lib/generators/tanstack-query.js.map +1 -0
- package/lib/generators/transformers.d.ts +19 -0
- package/lib/generators/transformers.d.ts.map +1 -0
- package/lib/generators/transformers.js +28 -0
- package/lib/generators/transformers.js.map +1 -0
- package/lib/generators/types.d.ts +66 -0
- package/lib/generators/types.d.ts.map +1 -0
- package/lib/generators/types.js +2 -0
- package/lib/generators/types.js.map +1 -0
- package/lib/generators/zod.d.ts +14 -0
- package/lib/generators/zod.d.ts.map +1 -0
- package/lib/generators/zod.js +23 -0
- package/lib/generators/zod.js.map +1 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +119 -0
- package/lib/index.js.map +1 -0
- package/lib/intermediate-representation/build.d.ts +4 -0
- package/lib/intermediate-representation/build.d.ts.map +1 -0
- package/lib/intermediate-representation/build.js +761 -0
- package/lib/intermediate-representation/build.js.map +1 -0
- package/lib/intermediate-representation/model.d.ts +275 -0
- package/lib/intermediate-representation/model.d.ts.map +1 -0
- package/lib/intermediate-representation/model.js +5 -0
- package/lib/intermediate-representation/model.js.map +1 -0
- package/lib/intermediate-representation/normalize-swagger2.d.ts +10 -0
- package/lib/intermediate-representation/normalize-swagger2.d.ts.map +1 -0
- package/lib/intermediate-representation/normalize-swagger2.js +210 -0
- package/lib/intermediate-representation/normalize-swagger2.js.map +1 -0
- package/lib/intermediate-representation/sanitize-identifiers.d.ts +30 -0
- package/lib/intermediate-representation/sanitize-identifiers.d.ts.map +1 -0
- package/lib/intermediate-representation/sanitize-identifiers.js +153 -0
- package/lib/intermediate-representation/sanitize-identifiers.js.map +1 -0
- package/lib/loader.d.ts +4 -0
- package/lib/loader.d.ts.map +1 -0
- package/lib/loader.js +14 -0
- package/lib/loader.js.map +1 -0
- package/lib/plugin.d.ts +19 -0
- package/lib/plugin.d.ts.map +1 -0
- package/lib/plugin.js +41 -0
- package/lib/plugin.js.map +1 -0
- package/lib/runtime/auth.d.ts +15 -0
- package/lib/runtime/auth.d.ts.map +1 -0
- package/lib/runtime/auth.js +67 -0
- package/lib/runtime/auth.js.map +1 -0
- package/lib/runtime/create-client.d.ts +35 -0
- package/lib/runtime/create-client.d.ts.map +1 -0
- package/lib/runtime/create-client.js +215 -0
- package/lib/runtime/create-client.js.map +1 -0
- package/lib/runtime/errors.d.ts +11 -0
- package/lib/runtime/errors.d.ts.map +1 -0
- package/lib/runtime/errors.js +25 -0
- package/lib/runtime/errors.js.map +1 -0
- package/lib/runtime/index.d.ts +14 -0
- package/lib/runtime/index.d.ts.map +1 -0
- package/lib/runtime/index.js +24 -0
- package/lib/runtime/index.js.map +1 -0
- package/lib/runtime/multipart.d.ts +9 -0
- package/lib/runtime/multipart.d.ts.map +1 -0
- package/lib/runtime/multipart.js +31 -0
- package/lib/runtime/multipart.js.map +1 -0
- package/lib/runtime/paginate.d.ts +36 -0
- package/lib/runtime/paginate.d.ts.map +1 -0
- package/lib/runtime/paginate.js +99 -0
- package/lib/runtime/paginate.js.map +1 -0
- package/lib/runtime/parse.d.ts +9 -0
- package/lib/runtime/parse.d.ts.map +1 -0
- package/lib/runtime/parse.js +37 -0
- package/lib/runtime/parse.js.map +1 -0
- package/lib/runtime/retry.d.ts +15 -0
- package/lib/runtime/retry.d.ts.map +1 -0
- package/lib/runtime/retry.js +51 -0
- package/lib/runtime/retry.js.map +1 -0
- package/lib/runtime/send.d.ts +31 -0
- package/lib/runtime/send.d.ts.map +1 -0
- package/lib/runtime/send.js +138 -0
- package/lib/runtime/send.js.map +1 -0
- package/lib/runtime/setup.d.ts +11 -0
- package/lib/runtime/setup.d.ts.map +1 -0
- package/lib/runtime/setup.js +13 -0
- package/lib/runtime/setup.js.map +1 -0
- package/lib/runtime/sse.d.ts +21 -0
- package/lib/runtime/sse.d.ts.map +1 -0
- package/lib/runtime/sse.js +163 -0
- package/lib/runtime/sse.js.map +1 -0
- package/lib/runtime/types.d.ts +232 -0
- package/lib/runtime/types.d.ts.map +1 -0
- package/lib/runtime/types.js +9 -0
- package/lib/runtime/types.js.map +1 -0
- package/lib/runtime/url.d.ts +25 -0
- package/lib/runtime/url.d.ts.map +1 -0
- package/lib/runtime/url.js +97 -0
- package/lib/runtime/url.js.map +1 -0
- package/lib/runtime-contract.d.ts +27 -0
- package/lib/runtime-contract.d.ts.map +1 -0
- package/lib/runtime-contract.js +14 -0
- package/lib/runtime-contract.js.map +1 -0
- package/lib/types.d.ts +118 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsdoc, ts } from './ts.js';
|
|
2
|
+
/**
|
|
3
|
+
* Emit `is<Member>(value): value is <Member>` type guards for every discriminated
|
|
4
|
+
* union with a usable discriminator — whether it is a top-level named schema
|
|
5
|
+
* (`MenuItem = A | B`) or nested inside one (e.g. the `items` of an array, the
|
|
6
|
+
* value of a property). Two discriminator sources:
|
|
7
|
+
*
|
|
8
|
+
* - Explicit: the union carries a `discriminator` (built from the spec).
|
|
9
|
+
* - Implicit: no discriminator, but every member is a ref to a named schema and
|
|
10
|
+
* they all constrain one shared property to a distinct string `const`.
|
|
11
|
+
*
|
|
12
|
+
* Nested unions only qualify when every member is a ref to a named schema, so the
|
|
13
|
+
* `value` parameter is a clean union of exported types. Guard names are globally
|
|
14
|
+
* deduped (`is<Member>`), keeping the first in document order — so a top-level
|
|
15
|
+
* union wins its nicer `value: <UnionName>` parameter over a nested re-occurrence.
|
|
16
|
+
* Undiscriminated unions are skipped — TypeScript can't soundly narrow them.
|
|
17
|
+
* Returns the guard declarations as nodes (empty when no union narrows).
|
|
18
|
+
*/
|
|
19
|
+
export function typeGuardStatements(schemas) {
|
|
20
|
+
const byName = new Map(schemas.map((s) => [s.name, s.schema]));
|
|
21
|
+
const nodes = [];
|
|
22
|
+
const emitted = new Set();
|
|
23
|
+
for (const named of schemas) {
|
|
24
|
+
for (const site of collectUnionSites(named)) {
|
|
25
|
+
const discriminator = site.union.discriminator ?? detectImplicitDiscriminator(site.union, byName);
|
|
26
|
+
if (!discriminator)
|
|
27
|
+
continue;
|
|
28
|
+
// Group discriminant values by target schema so two mapping keys pointing at
|
|
29
|
+
// the same type produce one guard (a duplicate `is<Name>` would not compile).
|
|
30
|
+
const valuesByTarget = new Map();
|
|
31
|
+
for (const entry of discriminator.mapping) {
|
|
32
|
+
if (!byName.has(entry.schemaName))
|
|
33
|
+
continue;
|
|
34
|
+
const existing = valuesByTarget.get(entry.schemaName);
|
|
35
|
+
if (existing)
|
|
36
|
+
existing.push(entry.value);
|
|
37
|
+
else
|
|
38
|
+
valuesByTarget.set(entry.schemaName, [entry.value]);
|
|
39
|
+
}
|
|
40
|
+
for (const [schemaName, values] of valuesByTarget) {
|
|
41
|
+
const guardName = `is${schemaName}`;
|
|
42
|
+
if (emitted.has(guardName))
|
|
43
|
+
continue;
|
|
44
|
+
emitted.add(guardName);
|
|
45
|
+
nodes.push(buildTypeGuard(site.makeParamType(), site.label, discriminator.propertyName, schemaName, values));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return nodes;
|
|
50
|
+
}
|
|
51
|
+
const { factory } = ts;
|
|
52
|
+
/**
|
|
53
|
+
* The discriminated-union sites reachable from a named schema, in a stable order:
|
|
54
|
+
* the schema itself (when it is a union), then any nested unions found by walking
|
|
55
|
+
* its tree. A top-level union keeps its name as the guard parameter; nested unions
|
|
56
|
+
* use their inline member union.
|
|
57
|
+
*/
|
|
58
|
+
function collectUnionSites(named) {
|
|
59
|
+
const sites = [];
|
|
60
|
+
const root = named.schema;
|
|
61
|
+
if (root.kind === 'union') {
|
|
62
|
+
sites.push({
|
|
63
|
+
union: root,
|
|
64
|
+
label: named.name,
|
|
65
|
+
makeParamType: () => factory.createTypeReferenceNode(named.name),
|
|
66
|
+
});
|
|
67
|
+
for (const member of root.members)
|
|
68
|
+
collectNestedSites(member, sites);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
collectNestedSites(root, sites);
|
|
72
|
+
}
|
|
73
|
+
return sites;
|
|
74
|
+
}
|
|
75
|
+
/** Walk a schema subtree, recording each nested all-named-ref union as a site. */
|
|
76
|
+
function collectNestedSites(schema, sites) {
|
|
77
|
+
switch (schema.kind) {
|
|
78
|
+
case 'union': {
|
|
79
|
+
const names = schema.members.map((m) => (m.kind === 'ref' ? m.name : undefined));
|
|
80
|
+
if (names.every((n) => n !== undefined)) {
|
|
81
|
+
sites.push({
|
|
82
|
+
union: schema,
|
|
83
|
+
label: names.join(' | '),
|
|
84
|
+
makeParamType: () => factory.createUnionTypeNode(names.map((n) => factory.createTypeReferenceNode(n))),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
for (const member of schema.members)
|
|
88
|
+
collectNestedSites(member, sites);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'array':
|
|
92
|
+
collectNestedSites(schema.items, sites);
|
|
93
|
+
break;
|
|
94
|
+
case 'record':
|
|
95
|
+
collectNestedSites(schema.value, sites);
|
|
96
|
+
break;
|
|
97
|
+
case 'object':
|
|
98
|
+
for (const prop of schema.properties)
|
|
99
|
+
collectNestedSites(prop.schema, sites);
|
|
100
|
+
break;
|
|
101
|
+
case 'intersection':
|
|
102
|
+
for (const member of schema.members)
|
|
103
|
+
collectNestedSites(member, sites);
|
|
104
|
+
break;
|
|
105
|
+
// scalar / literal / enum / ref / null / unknown / omit have no nested unions.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** `(value as Record<string, unknown>)[<prop>]` — the narrowed property access. */
|
|
109
|
+
function propertyAccess(propertyName) {
|
|
110
|
+
const recordType = factory.createTypeReferenceNode('Record', [
|
|
111
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
112
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),
|
|
113
|
+
]);
|
|
114
|
+
return factory.createElementAccessExpression(factory.createAsExpression(factory.createIdentifier('value'), recordType), factory.createStringLiteral(propertyName));
|
|
115
|
+
}
|
|
116
|
+
function buildTypeGuard(paramType, unionLabel, propertyName, schemaName, values) {
|
|
117
|
+
const access = propertyAccess(propertyName);
|
|
118
|
+
const check = values.length === 1
|
|
119
|
+
? factory.createBinaryExpression(access, factory.createToken(ts.SyntaxKind.EqualsEqualsEqualsToken), factory.createStringLiteral(values[0]))
|
|
120
|
+
: // `([...values] as readonly unknown[]).includes(<access>)`
|
|
121
|
+
factory.createCallExpression(factory.createPropertyAccessExpression(factory.createParenthesizedExpression(factory.createAsExpression(factory.createArrayLiteralExpression(values.map((v) => factory.createStringLiteral(v))), factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, factory.createArrayTypeNode(factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword))))), 'includes'), undefined, [access]);
|
|
122
|
+
const fn = factory.createFunctionDeclaration([factory.createModifier(ts.SyntaxKind.ExportKeyword)], undefined, `is${schemaName}`, undefined, [factory.createParameterDeclaration(undefined, undefined, 'value', undefined, paramType)], factory.createTypePredicateNode(undefined, 'value', factory.createTypeReferenceNode(schemaName)), factory.createBlock([factory.createReturnStatement(check)], true));
|
|
123
|
+
return jsdoc(fn, `Narrow a \`${unionLabel}\` to \`${schemaName}\` via its \`${propertyName}\` discriminant.`);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Detect an implicit discriminator: every member is a ref to a named schema,
|
|
127
|
+
* and they all pin one shared property to a distinct string literal. Returns
|
|
128
|
+
* `undefined` if no such property exists (so the union is left without guards).
|
|
129
|
+
*/
|
|
130
|
+
function detectImplicitDiscriminator(union, byName) {
|
|
131
|
+
const memberNames = [];
|
|
132
|
+
for (const member of union.members) {
|
|
133
|
+
if (member.kind !== 'ref')
|
|
134
|
+
return undefined;
|
|
135
|
+
const target = byName.get(member.name);
|
|
136
|
+
if (!target)
|
|
137
|
+
return undefined;
|
|
138
|
+
memberNames.push(member.name);
|
|
139
|
+
}
|
|
140
|
+
if (memberNames.length < 2)
|
|
141
|
+
return undefined;
|
|
142
|
+
const literalsPerMember = memberNames.map((name) => literalPropsOf(byName.get(name)));
|
|
143
|
+
for (const propName of Object.keys(literalsPerMember[0])) {
|
|
144
|
+
if (!literalsPerMember.every((props) => propName in props))
|
|
145
|
+
continue;
|
|
146
|
+
const values = literalsPerMember.map((props) => props[propName]);
|
|
147
|
+
if (!values.every((v) => typeof v === 'string'))
|
|
148
|
+
continue;
|
|
149
|
+
if (new Set(values).size !== values.length)
|
|
150
|
+
continue;
|
|
151
|
+
return {
|
|
152
|
+
propertyName: propName,
|
|
153
|
+
mapping: memberNames.map((name, i) => ({
|
|
154
|
+
value: values[i],
|
|
155
|
+
schemaName: name,
|
|
156
|
+
})),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Collect a schema's literal-valued properties (name → const value), descending
|
|
163
|
+
* through `intersection` members (the shape `allOf` produces). Only inline
|
|
164
|
+
* object/intersection members are inspected; nested refs are not resolved.
|
|
165
|
+
*/
|
|
166
|
+
function literalPropsOf(schema) {
|
|
167
|
+
const out = {};
|
|
168
|
+
const collect = (s) => {
|
|
169
|
+
if (s.kind === 'object') {
|
|
170
|
+
for (const prop of s.properties) {
|
|
171
|
+
if (prop.schema.kind === 'literal')
|
|
172
|
+
out[prop.name] = prop.schema.value;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (s.kind === 'intersection') {
|
|
176
|
+
for (const member of s.members)
|
|
177
|
+
collect(member);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
collect(schema);
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=type-guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-guards.js","sourceRoot":"","sources":["../../src/emitters/type-guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { NamedSchemaModel, SchemaModel } from '../intermediate-representation/model.js';
|
|
2
|
+
import { ts } from './ts.js';
|
|
3
|
+
/**
|
|
4
|
+
* How named string enums are emitted:
|
|
5
|
+
* - `'union'`: only the string-literal union type (`type X = "a" | "b"`).
|
|
6
|
+
* - `'const-object'`: the union type *and* a sibling
|
|
7
|
+
* `export const X = { a: "a", b: "b" } as const;` so callers can reference
|
|
8
|
+
* the values at runtime (`X.a`).
|
|
9
|
+
*/
|
|
10
|
+
export type EnumStyle = 'union' | 'const-object';
|
|
11
|
+
/**
|
|
12
|
+
* How `format: date-time`/`date` string fields are typed:
|
|
13
|
+
* - `'string'` (default): the wire shape — an ISO string.
|
|
14
|
+
* - `'Date'`: a `Date` reference. Opt-in; pair with the `transformers` generator
|
|
15
|
+
* so the runtime value matches (the client stays zero-dep — `Date` is standard).
|
|
16
|
+
*/
|
|
17
|
+
export type DateType = 'string' | 'Date';
|
|
18
|
+
/** The model type aliases (and const-object enum companions) as nodes. */
|
|
19
|
+
export declare function typesStatements(schemas: NamedSchemaModel[], enumStyle: EnumStyle, dateType?: DateType): ts.Statement[];
|
|
20
|
+
export declare function renderSchema(schema: SchemaModel, dateType?: DateType): string;
|
|
21
|
+
/** Build the TypeScript type node for an IR schema. */
|
|
22
|
+
export declare function schemaToTypeNode(schema: SchemaModel, dateType?: DateType): ts.TypeNode;
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/emitters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAIhB,WAAW,EACZ,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAAwC,EAAE,EAAE,MAAM,SAAS,CAAC;AAInE;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEzC,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,SAAS,EACpB,QAAQ,GAAE,QAAmB,GAC5B,EAAE,CAAC,SAAS,EAAE,CAqBhB;AAwCD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAmB,GAAG,MAAM,CAEvF;AAED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAmB,GAAG,EAAE,CAAC,QAAQ,CA6ChG"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { isIdentifier, safeIdent } from './identifier.js';
|
|
2
|
+
import { jsdocText } from './jsdoc.js';
|
|
3
|
+
import { jsdoc, literalExpression, printNodes, ts } from './ts.js';
|
|
4
|
+
const { factory } = ts;
|
|
5
|
+
/** The model type aliases (and const-object enum companions) as nodes. */
|
|
6
|
+
export function typesStatements(schemas, enumStyle, dateType = 'string') {
|
|
7
|
+
const nodes = [];
|
|
8
|
+
for (const s of schemas) {
|
|
9
|
+
nodes.push(jsdocOn(factory.createTypeAliasDeclaration([factory.createModifier(ts.SyntaxKind.ExportKeyword)], s.name, undefined, schemaToTypeNode(s.schema, dateType)), s.schema.description ?? s.description, s.schema.metadata));
|
|
10
|
+
if (enumStyle === 'const-object') {
|
|
11
|
+
const constObject = enumConstObject(s);
|
|
12
|
+
if (constObject)
|
|
13
|
+
nodes.push(constObject);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return nodes;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* For a named **string** enum, build a runtime companion
|
|
20
|
+
* `export const X = { a: "a", … } as const;` that cohabits with the same-named
|
|
21
|
+
* type (TypeScript allows a type and value to share an identifier). This lets
|
|
22
|
+
* callers reference values at runtime (`X.a`) instead of retyping literals.
|
|
23
|
+
*
|
|
24
|
+
* Returns `undefined` (so only the type union is emitted) when:
|
|
25
|
+
* - the schema isn't a string enum (integer/boolean enums gain nothing), or
|
|
26
|
+
* - any value isn't a valid JS identifier (e.g. `"menu:read"`) — we don't emit
|
|
27
|
+
* a half-usable object with quoted keys.
|
|
28
|
+
*/
|
|
29
|
+
function enumConstObject(named) {
|
|
30
|
+
const schema = named.schema;
|
|
31
|
+
if (schema.kind !== 'enum' || schema.scalar !== 'string')
|
|
32
|
+
return undefined;
|
|
33
|
+
if (!schema.values.every((v) => typeof v === 'string' && isIdentifier(v)))
|
|
34
|
+
return undefined;
|
|
35
|
+
const object = factory.createObjectLiteralExpression(schema.values.map((v) => factory.createPropertyAssignment(v, factory.createStringLiteral(v))), true);
|
|
36
|
+
return factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([
|
|
37
|
+
factory.createVariableDeclaration(named.name, undefined, undefined, factory.createAsExpression(object, factory.createTypeReferenceNode('const'))),
|
|
38
|
+
], ts.NodeFlags.Const));
|
|
39
|
+
}
|
|
40
|
+
export function renderSchema(schema, dateType = 'string') {
|
|
41
|
+
return printNodes([schemaToTypeNode(schema, dateType)]);
|
|
42
|
+
}
|
|
43
|
+
/** Build the TypeScript type node for an IR schema. */
|
|
44
|
+
export function schemaToTypeNode(schema, dateType = 'string') {
|
|
45
|
+
switch (schema.kind) {
|
|
46
|
+
case 'scalar':
|
|
47
|
+
return scalarTypeNode(schema.scalar, schema.metadata, dateType);
|
|
48
|
+
case 'ref':
|
|
49
|
+
return factory.createTypeReferenceNode(schema.name);
|
|
50
|
+
case 'literal':
|
|
51
|
+
return factory.createLiteralTypeNode(literalExpression(schema.value));
|
|
52
|
+
case 'enum': {
|
|
53
|
+
const members = schema.values.map((v) => factory.createLiteralTypeNode(literalExpression(v)));
|
|
54
|
+
// A single-value enum is just that literal — wrapping it in a one-member
|
|
55
|
+
// union would make the printer parenthesize it inside `T[]` (`("a")[]`).
|
|
56
|
+
return members.length === 1 ? members[0] : factory.createUnionTypeNode(members);
|
|
57
|
+
}
|
|
58
|
+
case 'null':
|
|
59
|
+
return factory.createLiteralTypeNode(factory.createNull());
|
|
60
|
+
case 'unknown':
|
|
61
|
+
return factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
62
|
+
case 'array':
|
|
63
|
+
// The printer parenthesizes union/intersection element types itself
|
|
64
|
+
// (`(string | null)[]`), so just hand it the element node.
|
|
65
|
+
return factory.createArrayTypeNode(schemaToTypeNode(schema.items, dateType));
|
|
66
|
+
case 'record':
|
|
67
|
+
return factory.createTypeReferenceNode('Record', [
|
|
68
|
+
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
|
|
69
|
+
schemaToTypeNode(schema.value, dateType),
|
|
70
|
+
]);
|
|
71
|
+
case 'object':
|
|
72
|
+
return factory.createTypeLiteralNode(schema.properties.map((p) => propertySignature(p, dateType)));
|
|
73
|
+
case 'union':
|
|
74
|
+
return factory.createUnionTypeNode(schema.members.map((m) => schemaToTypeNode(m, dateType)));
|
|
75
|
+
case 'intersection':
|
|
76
|
+
return factory.createIntersectionTypeNode(schema.members.map((m) => schemaToTypeNode(m, dateType)));
|
|
77
|
+
case 'omit':
|
|
78
|
+
return factory.createTypeReferenceNode('Omit', [
|
|
79
|
+
factory.createTypeReferenceNode(schema.base),
|
|
80
|
+
factory.createUnionTypeNode(schema.keys.map((k) => factory.createLiteralTypeNode(factory.createStringLiteral(k)))),
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function propertySignature(p, dateType) {
|
|
85
|
+
// `readOnly` (server-managed) props get the `readonly` modifier so consumer
|
|
86
|
+
// write-type utilities (OmitReadOnly<T>) can strip them and assignment is
|
|
87
|
+
// flagged. Request-body types already drop these via `Omit` in the IR.
|
|
88
|
+
const modifiers = p.readOnly
|
|
89
|
+
? [factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)]
|
|
90
|
+
: undefined;
|
|
91
|
+
const sig = factory.createPropertySignature(modifiers, propertyName(p.name), p.required ? undefined : factory.createToken(ts.SyntaxKind.QuestionToken), schemaToTypeNode(p.schema, dateType));
|
|
92
|
+
return jsdocOn(sig, p.description, p.schema.metadata);
|
|
93
|
+
}
|
|
94
|
+
/** A property name: a bare identifier when valid, a quoted string literal otherwise. */
|
|
95
|
+
function propertyName(name) {
|
|
96
|
+
const safe = safeIdent(name);
|
|
97
|
+
return safe === name ? factory.createIdentifier(name) : factory.createStringLiteral(name);
|
|
98
|
+
}
|
|
99
|
+
function scalarTypeNode(kind, metadata, dateType) {
|
|
100
|
+
switch (kind) {
|
|
101
|
+
case 'string':
|
|
102
|
+
// `format: binary` is raw byte content (file uploads / octet-stream), not text —
|
|
103
|
+
// surface it as `Blob` (the web standard; a `File` is assignable to it). `byte`
|
|
104
|
+
// (base64) stays a `string`.
|
|
105
|
+
if (metadata?.format === 'binary') {
|
|
106
|
+
return factory.createTypeReferenceNode('Blob');
|
|
107
|
+
}
|
|
108
|
+
// Opt-in: a `date-time`/`date` string surfaces as `Date` under `dateType:
|
|
109
|
+
// 'Date'`; everything else (and the default) stays the `string` keyword.
|
|
110
|
+
if (dateType === 'Date' &&
|
|
111
|
+
(metadata?.format === 'date-time' || metadata?.format === 'date')) {
|
|
112
|
+
return factory.createTypeReferenceNode('Date');
|
|
113
|
+
}
|
|
114
|
+
return factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
115
|
+
case 'number':
|
|
116
|
+
case 'integer':
|
|
117
|
+
return factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
|
|
118
|
+
case 'boolean':
|
|
119
|
+
return factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Attach a JSDoc block (description + metadata tags) to `node`, if any. */
|
|
123
|
+
function jsdocOn(node, text, metadata) {
|
|
124
|
+
const body = jsdocText(text, metadata);
|
|
125
|
+
return body === undefined ? node : jsdoc(node, body);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/emitters/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ApiModel, OperationModel } from '../intermediate-representation/model.js';
|
|
2
|
+
import { ts } from './ts.js';
|
|
3
|
+
/**
|
|
4
|
+
* The operations a wrapper generator can wrap, with skips reported to the user under
|
|
5
|
+
* `label` (the generator name). Two kinds are dropped:
|
|
6
|
+
*
|
|
7
|
+
* - **SSE operations** — the sdk exposes these as async generators (streams), not
|
|
8
|
+
* request/response functions, so a query/mutation hook cannot wrap them.
|
|
9
|
+
* - **`<Op>Variables` name collisions** — a wrapper types its inputs as the sdk's
|
|
10
|
+
* `<Op>Variables`; when that name collides with a schema the sdk suppresses the alias,
|
|
11
|
+
* so the import would resolve to the schema (a wrong/broken type). The sdk function still
|
|
12
|
+
* works; renaming the schema or the operation restores the wrapper.
|
|
13
|
+
*/
|
|
14
|
+
export declare function wrappableOperations(model: ApiModel, label: string): OperationModel[];
|
|
15
|
+
/** Query operations are the safe, cacheable methods. Everything else is a mutation. */
|
|
16
|
+
export declare function isQuery(op: OperationModel): boolean;
|
|
17
|
+
/** Whether the operation has any inputs — i.e. a `<Op>Variables` type exists in the sdk. */
|
|
18
|
+
export declare function hasInputs(op: OperationModel): boolean;
|
|
19
|
+
/** The operation's `<Op>Variables` type name (the sdk's grouped-input alias). */
|
|
20
|
+
export declare function variablesName(op: OperationModel): string;
|
|
21
|
+
/** A `vars: <Op>Variables` parameter. */
|
|
22
|
+
export declare function varsParam(op: OperationModel): ts.ParameterDeclaration;
|
|
23
|
+
/** An `init?: RequestOptions` parameter. */
|
|
24
|
+
export declare function initParam(): ts.ParameterDeclaration;
|
|
25
|
+
/**
|
|
26
|
+
* The forwarding call to the sdk operation function. Argument order comes from the
|
|
27
|
+
* shared `operationSignature`, so it lines up with the sdk's parameter list by
|
|
28
|
+
* construction. `grouped` passes the source object (when inputs); `flat` spreads
|
|
29
|
+
* `<source>.<pathIdent>` (URL-template order), then `<source>.params` / `.body` /
|
|
30
|
+
* `.headers` for the slots the op has. `init` is appended last when `withInit`
|
|
31
|
+
* (the sdk function's trailing `RequestOptions`).
|
|
32
|
+
*/
|
|
33
|
+
export declare function sdkCall(op: OperationModel, argsStyle: 'flat' | 'grouped', source: string, withInit: boolean): ts.Expression;
|
|
34
|
+
/**
|
|
35
|
+
* The named import from the sdk module: the wrapped opFns as value specifiers, then
|
|
36
|
+
* the referenced `<Op>Variables` types + `RequestOptions` (when any query op) as
|
|
37
|
+
* `type` specifiers, each group sorted.
|
|
38
|
+
*/
|
|
39
|
+
export declare function sdkNamedImport(ops: OperationModel[], sdkModule: string, hasQuery: boolean): ts.Statement;
|
|
40
|
+
//# sourceMappingURL=wrapper-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper-support.d.ts","sourceRoot":"","sources":["../../src/emitters/wrapper-support.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAGxF,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAI7B;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoBpF;AAQD,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAEnD;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAErD;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAExD;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,GAAG,EAAE,CAAC,oBAAoB,CAQrE;AAED,4CAA4C;AAC5C,wBAAgB,SAAS,IAAI,EAAE,CAAC,oBAAoB,CAQnD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,EAAE,EAAE,cAAc,EAClB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,GAChB,EAAE,CAAC,UAAU,CAkBf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GAChB,EAAE,CAAC,SAAS,CAkBd"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Shared support for the data-fetching wrapper generators (`swr`, `tanstack-query`).
|
|
2
|
+
// Both wrap the sdk's exported operation functions, so they agree on which operations
|
|
3
|
+
// are wrappable and on the `vars`/`init` parameter shape. Keeping that agreement in one
|
|
4
|
+
// place stops the two emitters from drifting (and makes a third adapter cheap). The
|
|
5
|
+
// per-operation factory/hook bodies stay in each emitter — only the cross-cutting
|
|
6
|
+
// calling-convention pieces live here.
|
|
7
|
+
import { logger } from '@redocly/openapi-core';
|
|
8
|
+
import { operationSignature } from './operation-signature.js';
|
|
9
|
+
import { isSseOp } from './sse.js';
|
|
10
|
+
import { ts } from './ts.js';
|
|
11
|
+
const { factory } = ts;
|
|
12
|
+
/**
|
|
13
|
+
* The operations a wrapper generator can wrap, with skips reported to the user under
|
|
14
|
+
* `label` (the generator name). Two kinds are dropped:
|
|
15
|
+
*
|
|
16
|
+
* - **SSE operations** — the sdk exposes these as async generators (streams), not
|
|
17
|
+
* request/response functions, so a query/mutation hook cannot wrap them.
|
|
18
|
+
* - **`<Op>Variables` name collisions** — a wrapper types its inputs as the sdk's
|
|
19
|
+
* `<Op>Variables`; when that name collides with a schema the sdk suppresses the alias,
|
|
20
|
+
* so the import would resolve to the schema (a wrong/broken type). The sdk function still
|
|
21
|
+
* works; renaming the schema or the operation restores the wrapper.
|
|
22
|
+
*/
|
|
23
|
+
export function wrappableOperations(model, label) {
|
|
24
|
+
const all = model.services.flatMap((s) => s.operations);
|
|
25
|
+
const sse = all.filter(isSseOp);
|
|
26
|
+
if (sse.length > 0) {
|
|
27
|
+
logger.warn(`generate-client: ${label} skipped ${sse.length} server-sent-events operation(s) — iterate the sdk's exported async generators directly: ${sse
|
|
28
|
+
.map((op) => op.name)
|
|
29
|
+
.join(', ')}.\n`);
|
|
30
|
+
}
|
|
31
|
+
const schemaNames = new Set(model.schemas.map((s) => s.name));
|
|
32
|
+
const clashing = all.filter((op) => !isSseOp(op) && collides(op, schemaNames));
|
|
33
|
+
if (clashing.length > 0) {
|
|
34
|
+
logger.warn(`generate-client: ${label} skipped ${clashing.length} operation(s) whose variables type name collides with a schema — rename the schema or the operation: ${clashing
|
|
35
|
+
.map((op) => op.name)
|
|
36
|
+
.join(', ')}.\n`);
|
|
37
|
+
}
|
|
38
|
+
return all.filter((op) => !isSseOp(op) && !collides(op, schemaNames));
|
|
39
|
+
}
|
|
40
|
+
/** Whether the operation's `<Op>Variables` type name collides with a named schema. */
|
|
41
|
+
function collides(op, schemaNames) {
|
|
42
|
+
const sig = operationSignature(op);
|
|
43
|
+
return sig.hasInputs && schemaNames.has(sig.variablesTypeName);
|
|
44
|
+
}
|
|
45
|
+
/** Query operations are the safe, cacheable methods. Everything else is a mutation. */
|
|
46
|
+
export function isQuery(op) {
|
|
47
|
+
return op.method === 'get' || op.method === 'head';
|
|
48
|
+
}
|
|
49
|
+
/** Whether the operation has any inputs — i.e. a `<Op>Variables` type exists in the sdk. */
|
|
50
|
+
export function hasInputs(op) {
|
|
51
|
+
return operationSignature(op).hasInputs;
|
|
52
|
+
}
|
|
53
|
+
/** The operation's `<Op>Variables` type name (the sdk's grouped-input alias). */
|
|
54
|
+
export function variablesName(op) {
|
|
55
|
+
return operationSignature(op).variablesTypeName;
|
|
56
|
+
}
|
|
57
|
+
/** A `vars: <Op>Variables` parameter. */
|
|
58
|
+
export function varsParam(op) {
|
|
59
|
+
return factory.createParameterDeclaration(undefined, undefined, 'vars', undefined, factory.createTypeReferenceNode(variablesName(op)));
|
|
60
|
+
}
|
|
61
|
+
/** An `init?: RequestOptions` parameter. */
|
|
62
|
+
export function initParam() {
|
|
63
|
+
return factory.createParameterDeclaration(undefined, undefined, 'init', factory.createToken(ts.SyntaxKind.QuestionToken), factory.createTypeReferenceNode('RequestOptions'));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The forwarding call to the sdk operation function. Argument order comes from the
|
|
67
|
+
* shared `operationSignature`, so it lines up with the sdk's parameter list by
|
|
68
|
+
* construction. `grouped` passes the source object (when inputs); `flat` spreads
|
|
69
|
+
* `<source>.<pathIdent>` (URL-template order), then `<source>.params` / `.body` /
|
|
70
|
+
* `.headers` for the slots the op has. `init` is appended last when `withInit`
|
|
71
|
+
* (the sdk function's trailing `RequestOptions`).
|
|
72
|
+
*/
|
|
73
|
+
export function sdkCall(op, argsStyle, source, withInit) {
|
|
74
|
+
const sig = operationSignature(op);
|
|
75
|
+
const sourceIdent = factory.createIdentifier(source);
|
|
76
|
+
const args = [];
|
|
77
|
+
if (argsStyle === 'grouped') {
|
|
78
|
+
if (sig.hasInputs)
|
|
79
|
+
args.push(sourceIdent);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
for (const { ident } of sig.pathParams) {
|
|
83
|
+
args.push(factory.createPropertyAccessExpression(sourceIdent, ident));
|
|
84
|
+
}
|
|
85
|
+
if (sig.hasQuery)
|
|
86
|
+
args.push(factory.createPropertyAccessExpression(sourceIdent, 'params'));
|
|
87
|
+
if (sig.hasBody)
|
|
88
|
+
args.push(factory.createPropertyAccessExpression(sourceIdent, 'body'));
|
|
89
|
+
if (sig.hasHeaders)
|
|
90
|
+
args.push(factory.createPropertyAccessExpression(sourceIdent, 'headers'));
|
|
91
|
+
}
|
|
92
|
+
if (withInit)
|
|
93
|
+
args.push(factory.createIdentifier('init'));
|
|
94
|
+
return factory.createCallExpression(factory.createIdentifier(op.name), undefined, args);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The named import from the sdk module: the wrapped opFns as value specifiers, then
|
|
98
|
+
* the referenced `<Op>Variables` types + `RequestOptions` (when any query op) as
|
|
99
|
+
* `type` specifiers, each group sorted.
|
|
100
|
+
*/
|
|
101
|
+
export function sdkNamedImport(ops, sdkModule, hasQuery) {
|
|
102
|
+
const values = ops.map((op) => op.name).sort();
|
|
103
|
+
const types = ops.filter(hasInputs).map(variablesName).sort();
|
|
104
|
+
if (hasQuery)
|
|
105
|
+
types.push('RequestOptions');
|
|
106
|
+
const specifiers = [
|
|
107
|
+
...values.map((name) => factory.createImportSpecifier(false, undefined, factory.createIdentifier(name))),
|
|
108
|
+
...types.map((name) => factory.createImportSpecifier(true, undefined, factory.createIdentifier(name))),
|
|
109
|
+
];
|
|
110
|
+
return factory.createImportDeclaration(undefined, factory.createImportClause(false, undefined, factory.createNamedImports(specifiers)), factory.createStringLiteral(sdkModule));
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=wrapper-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper-support.js","sourceRoot":"","sources":["../../src/emitters/wrapper-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ApiModel, type SchemaModel } from '../intermediate-representation/model.js';
|
|
2
|
+
import { ts } from './ts.js';
|
|
3
|
+
type SchemaByName = ReadonlyMap<string, SchemaModel>;
|
|
4
|
+
/** Map an IR schema to the Zod expression that validates it. */
|
|
5
|
+
export declare function schemaToZodExpression(schema: SchemaModel, byName?: SchemaByName): ts.Expression;
|
|
6
|
+
/**
|
|
7
|
+
* Render the full zod module source: the component schemas, then — when any operation
|
|
8
|
+
* has a JSON body — the `operationSchemas` map and the `zodValidation` middleware.
|
|
9
|
+
* `''` when there is nothing to emit.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderZodModule(model: ApiModel): string;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/emitters/zod.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,QAAQ,EAKb,KAAK,WAAW,EACjB,MAAM,yCAAyC,CAAC;AAIjD,OAAO,EAA6C,EAAE,EAAE,MAAM,SAAS,CAAC;AA4BxE,KAAK,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAIrD,gEAAgE;AAChE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,WAAW,EACnB,MAAM,GAAE,YAAyB,GAChC,EAAE,CAAC,UAAU,CAEf;AA6XD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAWvD"}
|