@redocly/client-generator 0.7.11 → 0.7.12
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/eject-assets/generators/cli/docs.ts +1 -1
- package/eject-assets/generators/cli/engine-source.ts +1 -1
- package/eject-assets/generators/cli/index.ts +2 -2
- package/eject-assets/generators/cli/render.ts +1 -1
- package/eject-assets/generators/go/client.ts +1 -1
- package/eject-assets/generators/go/descriptor.ts +1 -1
- package/eject-assets/generators/go/index.ts +2 -2
- package/eject-assets/generators/go/models.ts +7 -2
- package/eject-assets/generators/go/naming.ts +1 -1
- package/eject-assets/generators/go/operations.ts +1 -1
- package/eject-assets/generators/go/pagination.ts +1 -1
- package/eject-assets/generators/go/types.ts +1 -1
- package/eject-assets/generators/mock/faker.ts +17 -9
- package/eject-assets/generators/mock/index.ts +4 -3
- package/eject-assets/generators/mock/render.ts +128 -9
- package/eject-assets/generators/mock/sample.ts +87 -4
- package/eject-assets/generators/mock/values.ts +1 -1
- package/eject-assets/generators/php/client.ts +1 -1
- package/eject-assets/generators/php/descriptor.ts +10 -1
- package/eject-assets/generators/php/index.ts +2 -2
- package/eject-assets/generators/php/models.ts +8 -3
- package/eject-assets/generators/php/naming.ts +1 -1
- package/eject-assets/generators/php/operations.ts +11 -6
- package/eject-assets/generators/php/pagination.ts +3 -2
- package/eject-assets/generators/php/types.ts +12 -2
- package/eject-assets/generators/python/client.ts +1 -1
- package/eject-assets/generators/python/descriptor.ts +1 -1
- package/eject-assets/generators/python/index.ts +3 -3
- package/eject-assets/generators/python/models.ts +9 -3
- package/eject-assets/generators/python/naming.ts +1 -1
- package/eject-assets/generators/python/operations.ts +6 -5
- package/eject-assets/generators/python/pagination.ts +1 -1
- package/eject-assets/generators/python/types.ts +1 -1
- package/eject-assets/generators/swr/index.ts +2 -2
- package/eject-assets/generators/swr/render.ts +1 -1
- package/eject-assets/generators/tanstack-query/index.ts +2 -2
- package/eject-assets/generators/tanstack-query/render.ts +6 -5
- package/eject-assets/generators/transformers/index.ts +2 -2
- package/eject-assets/generators/transformers/render.ts +34 -7
- package/eject-assets/generators/typescript/banner.ts +1 -1
- package/eject-assets/generators/typescript/client.ts +1 -1
- package/eject-assets/generators/typescript/descriptor.ts +1 -1
- package/eject-assets/generators/typescript/index.ts +2 -2
- package/eject-assets/generators/typescript/inline-runtime.ts +1 -1
- package/eject-assets/generators/typescript/operation-signature.ts +1 -1
- package/eject-assets/generators/typescript/operation-types.ts +1 -1
- package/eject-assets/generators/typescript/operations.ts +1 -1
- package/eject-assets/generators/typescript/response-headers.ts +1 -1
- package/eject-assets/generators/typescript/type-guards.ts +1 -1
- package/eject-assets/generators/typescript/types.ts +1 -1
- package/eject-assets/generators/zod/index.ts +2 -2
- package/eject-assets/generators/zod/schemas.ts +1 -1
- package/eject-assets/skills/go-generator/SKILL.md +3 -0
- package/eject-assets/skills/mock-generator/SKILL.md +22 -0
- package/eject-assets/skills/php-generator/SKILL.md +9 -2
- package/eject-assets/skills/python-generator/SKILL.md +6 -0
- package/eject-assets/skills/tanstack-query-generator/SKILL.md +2 -1
- package/eject-assets/skills/transformers-generator/SKILL.md +4 -0
- package/eject-assets/skills/typescript-generator/SKILL.md +5 -0
- package/lib/authoring/schema.d.ts.map +1 -1
- package/lib/authoring/schema.js +4 -1
- package/lib/authoring/schema.js.map +1 -1
- package/lib/generators/go/models.d.ts.map +1 -1
- package/lib/generators/go/models.js +4 -1
- package/lib/generators/go/models.js.map +1 -1
- package/lib/generators/mock/faker.js +18 -8
- package/lib/generators/mock/faker.js.map +1 -1
- package/lib/generators/mock/index.d.ts.map +1 -1
- package/lib/generators/mock/index.js +2 -1
- package/lib/generators/mock/index.js.map +1 -1
- package/lib/generators/mock/render.d.ts +3 -1
- package/lib/generators/mock/render.d.ts.map +1 -1
- package/lib/generators/mock/render.js +119 -9
- package/lib/generators/mock/render.js.map +1 -1
- package/lib/generators/mock/sample.d.ts +18 -1
- package/lib/generators/mock/sample.d.ts.map +1 -1
- package/lib/generators/mock/sample.js +71 -2
- package/lib/generators/mock/sample.js.map +1 -1
- package/lib/generators/php/descriptor.d.ts +6 -0
- package/lib/generators/php/descriptor.d.ts.map +1 -1
- package/lib/generators/php/descriptor.js +8 -0
- package/lib/generators/php/descriptor.js.map +1 -1
- package/lib/generators/php/models.d.ts.map +1 -1
- package/lib/generators/php/models.js +5 -2
- package/lib/generators/php/models.js.map +1 -1
- package/lib/generators/php/operations.d.ts.map +1 -1
- package/lib/generators/php/operations.js +5 -5
- package/lib/generators/php/operations.js.map +1 -1
- package/lib/generators/php/pagination.d.ts.map +1 -1
- package/lib/generators/php/pagination.js +2 -1
- package/lib/generators/php/pagination.js.map +1 -1
- package/lib/generators/php/types.d.ts.map +1 -1
- package/lib/generators/php/types.js +13 -2
- package/lib/generators/php/types.js.map +1 -1
- package/lib/generators/python/index.js +1 -1
- package/lib/generators/python/index.js.map +1 -1
- package/lib/generators/python/models.d.ts.map +1 -1
- package/lib/generators/python/models.js +6 -2
- package/lib/generators/python/models.js.map +1 -1
- package/lib/generators/python/operations.d.ts.map +1 -1
- package/lib/generators/python/operations.js +5 -4
- package/lib/generators/python/operations.js.map +1 -1
- package/lib/generators/tanstack-query/render.js +5 -4
- package/lib/generators/tanstack-query/render.js.map +1 -1
- package/lib/generators/transformers/render.d.ts +1 -1
- package/lib/generators/transformers/render.d.ts.map +1 -1
- package/lib/generators/transformers/render.js +24 -5
- package/lib/generators/transformers/render.js.map +1 -1
- package/lib/generators/typescript/runtime/create-client.js +1 -1
- package/lib/generators/typescript/runtime/create-client.js.map +1 -1
- package/lib/generators/typescript/runtime/paginate.d.ts.map +1 -1
- package/lib/generators/typescript/runtime/paginate.js +5 -4
- package/lib/generators/typescript/runtime/paginate.js.map +1 -1
- package/lib/generators/typescript/runtime/send.d.ts.map +1 -1
- package/lib/generators/typescript/runtime/send.js +10 -4
- package/lib/generators/typescript/runtime/send.js.map +1 -1
- package/lib/generators/typescript/runtime/sse.d.ts.map +1 -1
- package/lib/generators/typescript/runtime/sse.js +6 -1
- package/lib/generators/typescript/runtime/sse.js.map +1 -1
- package/lib/intermediate-representation/build.d.ts.map +1 -1
- package/lib/intermediate-representation/build.js +51 -26
- package/lib/intermediate-representation/build.js.map +1 -1
- package/lib/intermediate-representation/model.d.ts +6 -2
- package/lib/intermediate-representation/model.d.ts.map +1 -1
- package/lib/intermediate-representation/model.js.map +1 -1
- package/lib/runtime-contract.d.ts +1 -1
- package/lib/runtime-contract.d.ts.map +1 -1
- package/lib/runtime-contract.js.map +1 -1
- package/lib/runtime-sources/python.d.ts +2 -2
- package/lib/runtime-sources/python.js +2 -2
- package/lib/runtime-sources/python.js.map +1 -1
- package/lib/runtime-sources/typescript.d.ts +10 -10
- package/lib/runtime-sources/typescript.js +10 -10
- package/lib/runtime-sources/typescript.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "cli" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator cli --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "cli" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator cli --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "cli" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator cli --update`.
|
|
@@ -86,5 +86,5 @@ export default {
|
|
|
86
86
|
docs: cliDocs,
|
|
87
87
|
requires: ["typescript","zod"],
|
|
88
88
|
errorModes: ["throw"],
|
|
89
|
-
requiresGenerator: '^0.7.
|
|
89
|
+
requiresGenerator: '^0.7.12',
|
|
90
90
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "cli" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator cli --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -332,5 +332,5 @@ export default {
|
|
|
332
332
|
"argsStyle": "inputs follow the target language's own idiom",
|
|
333
333
|
"importExt": "the generated file has no relative imports"
|
|
334
334
|
},
|
|
335
|
-
requiresGenerator: '^0.7.
|
|
335
|
+
requiresGenerator: '^0.7.12',
|
|
336
336
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -26,11 +26,16 @@ function writeStruct(
|
|
|
26
26
|
dateType: DateType,
|
|
27
27
|
description?: string
|
|
28
28
|
): void {
|
|
29
|
+
// A response never carries a `writeOnly` property, and responses decode into this same
|
|
30
|
+
// struct, so the property is optional even when the description requires it.
|
|
31
|
+
const fields = properties.map((property) =>
|
|
32
|
+
property.writeOnly ? { ...property, required: false } : property
|
|
33
|
+
);
|
|
29
34
|
printer.doc(exported(name), description);
|
|
30
35
|
printer.block(
|
|
31
36
|
`type ${exported(name)} struct {`,
|
|
32
37
|
() => {
|
|
33
|
-
for (const property of
|
|
38
|
+
for (const property of fields) {
|
|
34
39
|
const field = exported(property.name);
|
|
35
40
|
let fieldType = goType(property.schema, dateType);
|
|
36
41
|
let tag = `\`json:"${property.name}"\``;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "go" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator go --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "mock" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator mock --update`.
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from '@redocly/client-generator';
|
|
23
23
|
import { codeLiteral } from '@redocly/client-generator/printers/typescript';
|
|
24
24
|
|
|
25
|
-
import { splitIntersection } from './sample.ts';
|
|
25
|
+
import { numericRange, omitsFromResponse, splitIntersection } from './sample.ts';
|
|
26
26
|
import { expr, isObjectValue, type MockEntry, type MockValue, objectValue } from './values.ts';
|
|
27
27
|
|
|
28
28
|
/** The faker-call value for an IR schema. Refs resolve against `schemas`;
|
|
@@ -69,6 +69,7 @@ function walk(
|
|
|
69
69
|
case 'object':
|
|
70
70
|
return objectValue(
|
|
71
71
|
schema.properties.flatMap((p): MockEntry[] => {
|
|
72
|
+
if (omitsFromResponse(p)) return [];
|
|
72
73
|
const value = walk(p.schema, byName, visiting, dateType);
|
|
73
74
|
// A cyclic optional property is omitted; a cyclic required property is
|
|
74
75
|
// uninhabitable, so null is the only stand-in.
|
|
@@ -142,8 +143,8 @@ function scalarExpr(
|
|
|
142
143
|
): string {
|
|
143
144
|
if (meta?.format === 'binary') return 'new Blob([])';
|
|
144
145
|
if (scalar === 'boolean') return 'faker.datatype.boolean()';
|
|
145
|
-
if (scalar === 'integer') return `faker.number.int(${boundsArg(meta)})`;
|
|
146
|
-
if (scalar === 'number') return `faker.number.float(${boundsArg(meta)})`;
|
|
146
|
+
if (scalar === 'integer') return `faker.number.int(${boundsArg(scalar, meta)})`;
|
|
147
|
+
if (scalar === 'number') return `faker.number.float(${boundsArg(scalar, meta)})`;
|
|
147
148
|
switch (meta?.format) {
|
|
148
149
|
case 'email':
|
|
149
150
|
return 'faker.internet.email()';
|
|
@@ -173,13 +174,20 @@ function dateExpr(dateType: DateType, dateOnly: boolean): string {
|
|
|
173
174
|
return dateOnly ? `${iso}.slice(0, 10)` : iso;
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
/**
|
|
177
|
-
|
|
177
|
+
/**
|
|
178
|
+
* `{ min, max, multipleOf }` for a bounded numeric, or empty when unbounded. Both ends are
|
|
179
|
+
* always set, because faker's defaults (`0`, and `1` for floats) can sit on the wrong side
|
|
180
|
+
* of a single bound: the missing end is 100 steps away from the set one.
|
|
181
|
+
*/
|
|
182
|
+
function boundsArg(scalar: 'integer' | 'number', meta: SchemaMetadata | undefined): string {
|
|
183
|
+
const { min, max, step = 1 } = numericRange(scalar, meta);
|
|
184
|
+
if (min === undefined && max === undefined) return '';
|
|
178
185
|
const props = [
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
`min: ${min ?? (max ?? 0) - 100 * step}`,
|
|
187
|
+
`max: ${max ?? (min ?? 0) + 100 * step}`,
|
|
188
|
+
...(meta?.multipleOf !== undefined ? [`multipleOf: ${meta.multipleOf}`] : []),
|
|
181
189
|
];
|
|
182
|
-
return
|
|
190
|
+
return `{ ${props.join(', ')} }`;
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
/** `faker.helpers.multiple(() => <item>, { count: 1 })` — one element keeps output small.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "mock" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator mock --update`.
|
|
@@ -13,13 +13,14 @@ import { renderMockModule } from './render.ts';
|
|
|
13
13
|
* sdk client stays dependency-free. Output-mode-agnostic in v1 — one module beside
|
|
14
14
|
* the client. Emits nothing when there are no operations.
|
|
15
15
|
*/
|
|
16
|
-
export const mockGenerator: Generator = ({ model, output, banner, emit }) => {
|
|
16
|
+
export const mockGenerator: Generator = ({ model, output, banner, emit, pagination }) => {
|
|
17
17
|
const header = banner.map((line) => `// ${line}`).join('\n');
|
|
18
18
|
const content = renderMockModule(model, {
|
|
19
19
|
sdkModule: `./${output.stem}.${emit.importExt ?? 'js'}`,
|
|
20
20
|
dateType: emit.dateType,
|
|
21
21
|
mockData: emit.mockData,
|
|
22
22
|
mockSeed: emit.mockSeed,
|
|
23
|
+
pagination,
|
|
23
24
|
});
|
|
24
25
|
if (content === '') return [];
|
|
25
26
|
return [
|
|
@@ -31,5 +32,5 @@ export default {
|
|
|
31
32
|
name: 'mock',
|
|
32
33
|
run: mockGenerator,
|
|
33
34
|
requires: ["typescript"],
|
|
34
|
-
requiresGenerator: '^0.7.
|
|
35
|
+
requiresGenerator: '^0.7.12',
|
|
35
36
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "mock" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator mock --update`.
|
|
@@ -13,9 +13,13 @@ import {
|
|
|
13
13
|
allOperations,
|
|
14
14
|
type ApiModel,
|
|
15
15
|
type DateType,
|
|
16
|
+
flattenAllOf,
|
|
17
|
+
isNullable,
|
|
18
|
+
type ModelPagination,
|
|
16
19
|
type NamedSchemaModel,
|
|
17
20
|
type OperationModel,
|
|
18
21
|
type ResponseBodyModel,
|
|
22
|
+
schemaAtPointer,
|
|
19
23
|
type SchemaModel,
|
|
20
24
|
} from '@redocly/client-generator';
|
|
21
25
|
import {
|
|
@@ -30,6 +34,7 @@ import { sampleValue, SampleExpression } from './sample.ts';
|
|
|
30
34
|
import {
|
|
31
35
|
expr,
|
|
32
36
|
isObjectValue,
|
|
37
|
+
type MockEntry,
|
|
33
38
|
type MockValue,
|
|
34
39
|
objectValue,
|
|
35
40
|
renderMockValue,
|
|
@@ -54,6 +59,8 @@ export type MockOptions = {
|
|
|
54
59
|
mockData?: 'static' | 'faker';
|
|
55
60
|
/** When set in `'faker'` mode, emit a top-level `faker.seed(<n>);` so runs reproduce. */
|
|
56
61
|
mockSeed?: number;
|
|
62
|
+
/** The run's resolved pagination: a paginated handler serves the last page. */
|
|
63
|
+
pagination?: ModelPagination;
|
|
57
64
|
};
|
|
58
65
|
|
|
59
66
|
/** The body value for `schema` under the active data mode: a static literal tree
|
|
@@ -150,7 +157,7 @@ function codeIdent(value: string): string {
|
|
|
150
157
|
function handlerFor(op: OperationModel, model: ApiModel, opts: MockOptions): string {
|
|
151
158
|
const override = overrideParam(op, model, opts);
|
|
152
159
|
const params = override ?? '';
|
|
153
|
-
const call = `http.${codeIdent(op.method)}(${JSON.stringify(mswPath(op.path))},
|
|
160
|
+
const call = `http.${codeIdent(op.method)}(${JSON.stringify(mswPath(op.path))}, ${resolverFor(op, model, opts)})`;
|
|
154
161
|
return `export const ${codeIdent(op.name)}Handler = (${params}) => ${call};`;
|
|
155
162
|
}
|
|
156
163
|
|
|
@@ -212,8 +219,8 @@ function errorBodyType(op: OperationModel): string {
|
|
|
212
219
|
* A `ref` success body forwards `override` to `create<Schema>(override)`, so its type
|
|
213
220
|
* mirrors the factory's parameter (`Partial<Schema>`, or the full type when the factory
|
|
214
221
|
* replaces wholesale — see `factoryFor`). An inline object body spreads `override`, typed
|
|
215
|
-
* `Record<string, unknown
|
|
216
|
-
* override, so the handler takes no parameter.
|
|
222
|
+
* `Record<string, unknown>`, or `Partial<Omit<Schema, …>>` for an `omit` body. A body-less
|
|
223
|
+
* or non-object inline response has nothing to override, so the handler takes no parameter.
|
|
217
224
|
*/
|
|
218
225
|
function overrideParam(op: OperationModel, model: ApiModel, opts: MockOptions): string | undefined {
|
|
219
226
|
const success = op.successResponses[0];
|
|
@@ -226,16 +233,128 @@ function overrideParam(op: OperationModel, model: ApiModel, opts: MockOptions):
|
|
|
226
233
|
return `override?: ${type}`;
|
|
227
234
|
}
|
|
228
235
|
if (!isObjectValue(bodyValue(success.schema, model, opts))) return undefined;
|
|
236
|
+
if (success.schema.kind === 'omit') {
|
|
237
|
+
const keys = success.schema.keys.map((key) => JSON.stringify(key)).join(' | ');
|
|
238
|
+
return `override?: Partial<Omit<${success.schema.base}, ${keys}>>`;
|
|
239
|
+
}
|
|
229
240
|
return 'override?: Record<string, unknown>';
|
|
230
241
|
}
|
|
231
242
|
|
|
243
|
+
/**
|
|
244
|
+
* The handler's resolver. A paginated operation serves the LAST page, so `.pages()` over
|
|
245
|
+
* the default handlers ends after one page: a cursor page carries no next cursor (and a
|
|
246
|
+
* `false` "has more" flag), and a `body-link` page no next link; an offset or page-number
|
|
247
|
+
* page answers any position past the first with an empty item list, because those styles
|
|
248
|
+
* stop only on an empty page.
|
|
249
|
+
*/
|
|
250
|
+
function resolverFor(op: OperationModel, model: ApiModel, opts: MockOptions): string {
|
|
251
|
+
const spec = opts.pagination?.get(op.name)?.spec;
|
|
252
|
+
const success = op.successResponses[0];
|
|
253
|
+
if (!spec || spec.style === 'link' || !success)
|
|
254
|
+
return `() => ${responseExpression(op, model, opts)}`;
|
|
255
|
+
const page = bodyValue(success.schema, model, opts);
|
|
256
|
+
const status = statusCode(success.status);
|
|
257
|
+
// An object page spreads `override` in; a page that is the item array is replaced by it.
|
|
258
|
+
const takesOverride = overrideParam(op, model, opts) !== undefined;
|
|
259
|
+
const withOverride = (value: MockValue): MockValue => {
|
|
260
|
+
if (isObjectValue(value)) return spreadInto(value, 'override');
|
|
261
|
+
return takesOverride ? { kind: 'wrap', before: 'override ?? ', value, after: '' } : value;
|
|
262
|
+
};
|
|
263
|
+
const json = (value: MockValue): string => {
|
|
264
|
+
const data = renderMockValue(value, '');
|
|
265
|
+
return status === 200
|
|
266
|
+
? `HttpResponse.json(${data})`
|
|
267
|
+
: `HttpResponse.json(${data}, { status: ${status} })`;
|
|
268
|
+
};
|
|
269
|
+
if (spec.style === 'cursor' || spec.style === 'body-link') {
|
|
270
|
+
const next = spec.style === 'cursor' ? spec.nextCursor : spec.nextLink;
|
|
271
|
+
let last = withPointer(page, pointerKeys(next), cursorStop(success.schema, next, model));
|
|
272
|
+
if (spec.style === 'cursor' && spec.hasMore !== undefined)
|
|
273
|
+
last = withPointer(last, pointerKeys(spec.hasMore), expr('false'));
|
|
274
|
+
return `() => ${json(withOverride(last))}`;
|
|
275
|
+
}
|
|
276
|
+
const first = spec.style === 'page' ? 1 : 0;
|
|
277
|
+
const position = `Number(new URL(request.url).searchParams.get(${codeLiteral(spec.param)}) ?? ${first})`;
|
|
278
|
+
const empty = emptyPage(page, pointerKeys(spec.items));
|
|
279
|
+
return `({ request }) => ${position} > ${first} ? ${json(empty)} : ${json(withOverride(page))}`;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The page past the last one: the page with `override` spread in, and the items at `keys`
|
|
284
|
+
* set AFTER the spread, so an override that sets the items cannot refill the empty page.
|
|
285
|
+
* The top-level property that holds the items is written out from the sample.
|
|
286
|
+
*/
|
|
287
|
+
function emptyPage(page: MockValue, keys: string[]): MockValue {
|
|
288
|
+
if (keys.length === 0 || !isObjectValue(page)) return withPointer(page, keys, expr('[]'));
|
|
289
|
+
const [key, ...rest] = keys;
|
|
290
|
+
const isKey = (entry: MockEntry) => !('spread' in entry) && entry.key === key;
|
|
291
|
+
const holder = page.entries.find(isKey);
|
|
292
|
+
const inner = holder && !('spread' in holder) ? holder.value : objectValue([]);
|
|
293
|
+
return objectValue([
|
|
294
|
+
...page.entries.filter((entry) => !isKey(entry)),
|
|
295
|
+
{ spread: 'override' },
|
|
296
|
+
{ key, value: withPointer(inner, rest, expr('[]')) },
|
|
297
|
+
]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* What ends a cursor or `body-link` walk at `pointer`: `null` when the value is nullable,
|
|
302
|
+
* nothing (the property is left out) when it is optional, and an empty string otherwise.
|
|
303
|
+
*/
|
|
304
|
+
function cursorStop(schema: SchemaModel, pointer: string, model: ApiModel): MockValue | undefined {
|
|
305
|
+
const cursor = schemaAtPointer(schema, pointer, model);
|
|
306
|
+
if (cursor?.kind === 'null' || (cursor && isNullable(cursor))) return expr('null');
|
|
307
|
+
const keys = pointerKeys(pointer);
|
|
308
|
+
const parent = schemaAtPointer(schema, pointer.slice(0, pointer.lastIndexOf('/')), model);
|
|
309
|
+
const property =
|
|
310
|
+
parent &&
|
|
311
|
+
flattenAllOf(parent, model)?.properties.find((candidate) => candidate.name === keys.at(-1));
|
|
312
|
+
return property?.required === false ? undefined : expr('""');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** RFC 6901 pointer tokens (`~1` → `/`, `~0` → `~`); none for `''`, the whole value. */
|
|
316
|
+
function pointerKeys(pointer: string): string[] {
|
|
317
|
+
if (pointer === '') return [];
|
|
318
|
+
return pointer
|
|
319
|
+
.slice(1)
|
|
320
|
+
.split('/')
|
|
321
|
+
.map((token) => token.replaceAll('~1', '/').replaceAll('~0', '~'));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* `value` with the property at the `keys` path replaced (added when missing), or removed
|
|
326
|
+
* when `replacement` is `undefined`. An empty path replaces the whole value (a page that
|
|
327
|
+
* is the item array itself). Steps only through objects: a path that reaches into
|
|
328
|
+
* anything else leaves the value unchanged.
|
|
329
|
+
*/
|
|
330
|
+
function withPointer(
|
|
331
|
+
value: MockValue,
|
|
332
|
+
keys: string[],
|
|
333
|
+
replacement: MockValue | undefined
|
|
334
|
+
): MockValue {
|
|
335
|
+
if (keys.length === 0) return replacement ?? value;
|
|
336
|
+
if (!isObjectValue(value)) return value;
|
|
337
|
+
const [key, ...rest] = keys;
|
|
338
|
+
const found = value.entries.some((entry) => !('spread' in entry) && entry.key === key);
|
|
339
|
+
const entries = value.entries.flatMap((entry) => {
|
|
340
|
+
if ('spread' in entry || entry.key !== key) return [entry];
|
|
341
|
+
if (rest.length > 0) return [{ key, value: withPointer(entry.value, rest, replacement) }];
|
|
342
|
+
return replacement === undefined ? [] : [{ key, value: replacement }];
|
|
343
|
+
});
|
|
344
|
+
if (!found && rest.length === 0 && replacement !== undefined) {
|
|
345
|
+
entries.push({ key, value: replacement });
|
|
346
|
+
}
|
|
347
|
+
return objectValue(entries);
|
|
348
|
+
}
|
|
349
|
+
|
|
232
350
|
/**
|
|
233
351
|
* The handler's response. A primary success body becomes `HttpResponse.json(…)`:
|
|
234
|
-
* a `ref` body calls its named `create<Schema>(override)` factory; an inline body
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* response
|
|
352
|
+
* a `ref` body calls its named `create<Schema>(override)` factory; an inline body is
|
|
353
|
+
* sampled and printed in place with `...override` spread in. An `omit` body (a named
|
|
354
|
+
* schema without its `writeOnly` keys) is inline too, because the factory keeps the
|
|
355
|
+
* required ones. A success with no usable body (an `unknown` schema, or no success
|
|
356
|
+
* response at all) becomes a body-less `new HttpResponse(null, { status })`. The status
|
|
357
|
+
* is the success response's declared code, or 200 when it's `default`/absent.
|
|
239
358
|
*/
|
|
240
359
|
function responseExpression(op: OperationModel, model: ApiModel, opts: MockOptions): string {
|
|
241
360
|
const success = op.successResponses[0];
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "mock" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator mock --update`.
|
|
5
5
|
import {
|
|
6
6
|
type DateType,
|
|
7
7
|
type NamedSchemaModel,
|
|
8
|
+
type PropertyModel,
|
|
8
9
|
type ScalarKind,
|
|
9
10
|
type SchemaMetadata,
|
|
10
11
|
type SchemaModel,
|
|
@@ -97,7 +98,10 @@ export function splitIntersection(
|
|
|
97
98
|
members: SchemaModel[],
|
|
98
99
|
byName: Map<string, SchemaModel>
|
|
99
100
|
): { merged: SchemaModel | undefined; rest: SchemaModel[] } {
|
|
100
|
-
const properties = new Map<
|
|
101
|
+
const properties = new Map<
|
|
102
|
+
string,
|
|
103
|
+
{ schema: SchemaModel; required: boolean; writeOnly: boolean; rank: number }
|
|
104
|
+
>();
|
|
101
105
|
const rest: SchemaModel[] = [];
|
|
102
106
|
let sawObject = false;
|
|
103
107
|
for (const member of members) {
|
|
@@ -116,6 +120,7 @@ export function splitIntersection(
|
|
|
116
120
|
properties.set(property.name, {
|
|
117
121
|
schema: property.schema,
|
|
118
122
|
required: property.required || (existing?.required ?? false),
|
|
123
|
+
writeOnly: property.writeOnly === true || (existing?.writeOnly ?? false),
|
|
119
124
|
rank,
|
|
120
125
|
});
|
|
121
126
|
}
|
|
@@ -129,6 +134,7 @@ export function splitIntersection(
|
|
|
129
134
|
name,
|
|
130
135
|
schema: p.schema,
|
|
131
136
|
required: p.required,
|
|
137
|
+
...(p.writeOnly ? { writeOnly: true } : {}),
|
|
132
138
|
})),
|
|
133
139
|
},
|
|
134
140
|
rest,
|
|
@@ -195,7 +201,9 @@ function walk(
|
|
|
195
201
|
const meta = schema.metadata;
|
|
196
202
|
// An example/default is honored only when it inhabits the generated type — real specs
|
|
197
203
|
// carry `example: null` on non-nullable fields and defaults outside a narrowed enum
|
|
198
|
-
// (`enum: [cram-md5], default: none`); baking those would not type-check.
|
|
204
|
+
// (`enum: [cram-md5], default: none`); baking those would not type-check. A number
|
|
205
|
+
// outside its bounds or off its `multipleOf` step would fail the zod schema, so it is
|
|
206
|
+
// skipped too.
|
|
199
207
|
const inhabits = (value: unknown): boolean => {
|
|
200
208
|
if (value === null) {
|
|
201
209
|
return (
|
|
@@ -205,6 +213,16 @@ function walk(
|
|
|
205
213
|
}
|
|
206
214
|
if (schema.kind === 'enum') return (schema.values as unknown[]).includes(value);
|
|
207
215
|
if (schema.kind === 'literal') return value === schema.value;
|
|
216
|
+
if (
|
|
217
|
+
schema.kind === 'scalar' &&
|
|
218
|
+
(schema.scalar === 'integer' || schema.scalar === 'number') &&
|
|
219
|
+
typeof value === 'number'
|
|
220
|
+
) {
|
|
221
|
+
const { min, max, step } = numericRange(schema.scalar, meta);
|
|
222
|
+
// `toPrecision` drops float noise, so `0.3` counts as a multiple of `0.1`.
|
|
223
|
+
const onStep = step === undefined || Number.isInteger(Number((value / step).toPrecision(12)));
|
|
224
|
+
return onStep && (min === undefined || value >= min) && (max === undefined || value <= max);
|
|
225
|
+
}
|
|
208
226
|
return true;
|
|
209
227
|
};
|
|
210
228
|
if (meta?.example !== undefined && inhabits(meta.example)) return meta.example;
|
|
@@ -221,6 +239,7 @@ function walk(
|
|
|
221
239
|
case 'object':
|
|
222
240
|
return Object.fromEntries(
|
|
223
241
|
schema.properties.flatMap((p) => {
|
|
242
|
+
if (omitsFromResponse(p)) return [];
|
|
224
243
|
const value = walk(p.schema, byName, visiting, dateType);
|
|
225
244
|
// A cyclic optional property is omitted (a null would not satisfy `T | undefined`);
|
|
226
245
|
// a cyclic required property is uninhabitable, so null is the only stand-in.
|
|
@@ -292,9 +311,73 @@ function walk(
|
|
|
292
311
|
}
|
|
293
312
|
}
|
|
294
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Whether a mock leaves a property out. Mocks are response data, and a response never
|
|
316
|
+
* carries a `writeOnly` property. A required one stays, because the named type still
|
|
317
|
+
* demands it; a handler whose response omits it samples that `omit` shape instead.
|
|
318
|
+
*/
|
|
319
|
+
export function omitsFromResponse(property: PropertyModel): boolean {
|
|
320
|
+
return property.writeOnly === true && !property.required;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The inclusive range a numeric schema allows. `minimum`/`maximum` and the exclusive
|
|
325
|
+
* bounds narrow it, aligned to `multipleOf` (an integer steps by 1 without one). An
|
|
326
|
+
* exclusive bound on a number without a step moves in by 1, or to the middle of the
|
|
327
|
+
* range when the range is narrower than that. An unbounded side is `undefined`.
|
|
328
|
+
*/
|
|
329
|
+
export function numericRange(
|
|
330
|
+
scalar: 'integer' | 'number',
|
|
331
|
+
meta: SchemaMetadata | undefined
|
|
332
|
+
): { min?: number; max?: number; step?: number } {
|
|
333
|
+
const step = meta?.multipleOf ?? (scalar === 'integer' ? 1 : undefined);
|
|
334
|
+
// The multiple of `step` that `round` picks for `bound`; `toPrecision` drops float noise.
|
|
335
|
+
const onStep = (bound: number, size: number, round: (steps: number) => number): number =>
|
|
336
|
+
Number((round(bound / size) * size).toPrecision(15));
|
|
337
|
+
const lows: number[] = [];
|
|
338
|
+
const highs: number[] = [];
|
|
339
|
+
if (meta?.minimum !== undefined) {
|
|
340
|
+
const bound = meta.minimum;
|
|
341
|
+
lows.push(step === undefined ? bound : onStep(bound, step, Math.ceil));
|
|
342
|
+
}
|
|
343
|
+
if (meta?.exclusiveMinimum !== undefined) {
|
|
344
|
+
const bound = meta.exclusiveMinimum;
|
|
345
|
+
lows.push(
|
|
346
|
+
step === undefined ? bound + 1 : onStep(bound, step, (steps) => Math.floor(steps) + 1)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
if (meta?.maximum !== undefined) {
|
|
350
|
+
const bound = meta.maximum;
|
|
351
|
+
highs.push(step === undefined ? bound : onStep(bound, step, Math.floor));
|
|
352
|
+
}
|
|
353
|
+
if (meta?.exclusiveMaximum !== undefined) {
|
|
354
|
+
const bound = meta.exclusiveMaximum;
|
|
355
|
+
highs.push(
|
|
356
|
+
step === undefined ? bound - 1 : onStep(bound, step, (steps) => Math.ceil(steps) - 1)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
const min = lows.length > 0 ? Math.max(...lows) : undefined;
|
|
360
|
+
const max = highs.length > 0 ? Math.min(...highs) : undefined;
|
|
361
|
+
if (step === undefined && min !== undefined && max !== undefined && min > max) {
|
|
362
|
+
const low = Math.max(meta?.minimum ?? -Infinity, meta?.exclusiveMinimum ?? -Infinity);
|
|
363
|
+
const high = Math.min(meta?.maximum ?? Infinity, meta?.exclusiveMaximum ?? Infinity);
|
|
364
|
+
const middle = (low + high) / 2;
|
|
365
|
+
return { min: middle, max: middle };
|
|
366
|
+
}
|
|
367
|
+
return { min, max, step };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** `0` when the range allows it, else the end of the range nearest to `0`. */
|
|
371
|
+
function numberSample(scalar: 'integer' | 'number', meta: SchemaMetadata | undefined): number {
|
|
372
|
+
const { min, max } = numericRange(scalar, meta);
|
|
373
|
+
if (min !== undefined && min > 0) return min;
|
|
374
|
+
if (max !== undefined && max < 0) return max;
|
|
375
|
+
return 0;
|
|
376
|
+
}
|
|
377
|
+
|
|
295
378
|
function scalarSample(scalar: ScalarKind, meta: SchemaMetadata | undefined): unknown {
|
|
296
379
|
if (scalar === 'boolean') return true;
|
|
297
|
-
if (scalar === 'integer' || scalar === 'number') return
|
|
380
|
+
if (scalar === 'integer' || scalar === 'number') return numberSample(scalar, meta);
|
|
298
381
|
// Type-demanding formats (binary, and date/date-time under `dateType: 'Date'`) are
|
|
299
382
|
// handled earlier in `walk` via `typeDemandedExpression`; here the date formats fall
|
|
300
383
|
// through to the ISO-string path (the `dateType: 'string'` types them as `string`).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "mock" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator mock --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "php" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator php --update`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "php" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator php --update`.
|
|
@@ -30,6 +30,15 @@ export function phpSecurityLiteral(op: OperationModel, model: ApiModel): string
|
|
|
30
30
|
return `[${alternatives.join(', ')}]`;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* The `resolveAuth` argument: the table's `security` entry, or `[]` for an operation the
|
|
35
|
+
* table gives none. Reading an absent key with `?? []` reads as dead code to PHPStan,
|
|
36
|
+
* which knows the table's exact shape.
|
|
37
|
+
*/
|
|
38
|
+
export function phpSecurityArg(op: OperationModel, model: ApiModel): string {
|
|
39
|
+
return phpSecurityLiteral(op, model) === undefined ? '[]' : "$op['security']";
|
|
40
|
+
}
|
|
41
|
+
|
|
33
42
|
export function phpPaginationLiteral(rule: NeutralPaginationRule): string {
|
|
34
43
|
const fields = [
|
|
35
44
|
`'style' => ${phpString(rule.style)}`,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "php" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator php --update`.
|
|
@@ -234,5 +234,5 @@ export default {
|
|
|
234
234
|
"argsStyle": "inputs follow the target language's own idiom",
|
|
235
235
|
"importExt": "the generated file has no relative imports"
|
|
236
236
|
},
|
|
237
|
-
requiresGenerator: '^0.7.
|
|
237
|
+
requiresGenerator: '^0.7.12',
|
|
238
238
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "php" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator php --update`.
|
|
@@ -111,10 +111,15 @@ function writeClass(
|
|
|
111
111
|
dateType: DateType,
|
|
112
112
|
description?: string
|
|
113
113
|
): void {
|
|
114
|
+
// A response never carries a `writeOnly` property, and responses decode into this same
|
|
115
|
+
// class, so the property is optional even when the description requires it.
|
|
116
|
+
const fields = properties.map((property) =>
|
|
117
|
+
property.writeOnly ? { ...property, required: false } : property
|
|
118
|
+
);
|
|
114
119
|
// PHP requires defaulted parameters after required ones.
|
|
115
120
|
const ordered = [
|
|
116
|
-
...
|
|
117
|
-
...
|
|
121
|
+
...fields.filter((property) => property.required),
|
|
122
|
+
...fields.filter((property) => !property.required),
|
|
118
123
|
];
|
|
119
124
|
printer.doc(className(name), description);
|
|
120
125
|
printer.line(`final class ${className(name)}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Ejected from @redocly/client-generator@0.7.
|
|
1
|
+
// Ejected from @redocly/client-generator@0.7.12 — the built-in "php" generator.
|
|
2
2
|
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
3
|
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
4
|
// `redocly eject-generator php --update`.
|