@distilled.cloud/core 0.30.3 → 1.0.0-rc.2
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/lib/api.d.ts +165 -0
- package/lib/api.d.ts.map +1 -0
- package/lib/api.js +178 -0
- package/lib/api.js.map +1 -0
- package/lib/codegen/cli.d.ts +29 -0
- package/lib/codegen/cli.d.ts.map +1 -0
- package/lib/codegen/cli.js +165 -0
- package/lib/codegen/cli.js.map +1 -0
- package/lib/codegen/emit.d.ts +129 -0
- package/lib/codegen/emit.d.ts.map +1 -0
- package/lib/codegen/emit.js +105 -0
- package/lib/codegen/emit.js.map +1 -0
- package/lib/codegen/format.d.ts +23 -0
- package/lib/codegen/format.d.ts.map +1 -0
- package/lib/codegen/format.js +28 -0
- package/lib/codegen/format.js.map +1 -0
- package/lib/codegen/generator.d.ts +334 -0
- package/lib/codegen/generator.d.ts.map +1 -0
- package/lib/codegen/generator.js +691 -0
- package/lib/codegen/generator.js.map +1 -0
- package/lib/codegen/graph.d.ts +36 -0
- package/lib/codegen/graph.d.ts.map +1 -0
- package/lib/codegen/graph.js +136 -0
- package/lib/codegen/graph.js.map +1 -0
- package/lib/codegen/members.d.ts +25 -0
- package/lib/codegen/members.d.ts.map +1 -0
- package/lib/codegen/members.js +55 -0
- package/lib/codegen/members.js.map +1 -0
- package/lib/codegen/naming.d.ts +29 -0
- package/lib/codegen/naming.d.ts.map +1 -0
- package/lib/codegen/naming.js +74 -0
- package/lib/codegen/naming.js.map +1 -0
- package/lib/codegen/openapi-cli.d.ts +38 -0
- package/lib/codegen/openapi-cli.d.ts.map +1 -0
- package/lib/codegen/openapi-cli.js +107 -0
- package/lib/codegen/openapi-cli.js.map +1 -0
- package/lib/codegen/openapi.d.ts +115 -0
- package/lib/codegen/openapi.d.ts.map +1 -0
- package/lib/codegen/openapi.js +1220 -0
- package/lib/codegen/openapi.js.map +1 -0
- package/lib/codegen/operations.d.ts +24 -0
- package/lib/codegen/operations.d.ts.map +1 -0
- package/lib/codegen/operations.js +56 -0
- package/lib/codegen/operations.js.map +1 -0
- package/lib/codegen/pagination.d.ts +39 -0
- package/lib/codegen/pagination.d.ts.map +1 -0
- package/lib/codegen/pagination.js +33 -0
- package/lib/codegen/pagination.js.map +1 -0
- package/lib/codegen/prelude.d.ts +15 -0
- package/lib/codegen/prelude.d.ts.map +1 -0
- package/lib/codegen/prelude.js +60 -0
- package/lib/codegen/prelude.js.map +1 -0
- package/lib/error-category.d.ts +28 -0
- package/lib/error-category.d.ts.map +1 -0
- package/lib/error-category.js +46 -0
- package/lib/error-category.js.map +1 -0
- package/lib/errors.d.ts +1 -0
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +1 -0
- package/lib/errors.js.map +1 -1
- package/lib/json-patch.d.ts +25 -32
- package/lib/json-patch.d.ts.map +1 -1
- package/lib/json-patch.js +23 -95
- package/lib/json-patch.js.map +1 -1
- package/lib/pagination.d.ts +37 -51
- package/lib/pagination.d.ts.map +1 -1
- package/lib/pagination.js +72 -90
- package/lib/pagination.js.map +1 -1
- package/lib/protocol-http.d.ts +74 -0
- package/lib/protocol-http.d.ts.map +1 -0
- package/lib/protocol-http.js +554 -0
- package/lib/protocol-http.js.map +1 -0
- package/lib/protocol-rest.d.ts +124 -0
- package/lib/protocol-rest.d.ts.map +1 -0
- package/lib/protocol-rest.js +242 -0
- package/lib/protocol-rest.js.map +1 -0
- package/lib/retry.d.ts +8 -2
- package/lib/retry.d.ts.map +1 -1
- package/lib/retry.js +21 -15
- package/lib/retry.js.map +1 -1
- package/lib/schema.d.ts +7 -8
- package/lib/schema.d.ts.map +1 -1
- package/lib/schema.js +7 -8
- package/lib/schema.js.map +1 -1
- package/lib/trait.d.ts +150 -0
- package/lib/trait.d.ts.map +1 -0
- package/lib/trait.js +107 -0
- package/lib/trait.js.map +1 -0
- package/package.json +18 -75
- package/src/api.ts +446 -0
- package/src/codegen/cli.ts +268 -0
- package/src/codegen/emit.ts +207 -0
- package/src/codegen/format.ts +47 -0
- package/src/codegen/generator.ts +1153 -0
- package/src/codegen/graph.ts +151 -0
- package/src/codegen/members.ts +71 -0
- package/src/codegen/naming.ts +86 -0
- package/src/codegen/openapi-cli.ts +166 -0
- package/src/codegen/openapi.ts +1450 -0
- package/src/codegen/operations.ts +76 -0
- package/src/codegen/pagination.ts +71 -0
- package/src/codegen/prelude.ts +70 -0
- package/src/error-category.ts +84 -0
- package/src/errors.ts +2 -0
- package/src/json-patch.ts +26 -110
- package/src/pagination.ts +86 -142
- package/src/protocol-http.ts +699 -0
- package/src/protocol-rest.ts +367 -0
- package/src/retry.ts +20 -21
- package/src/schema.ts +7 -8
- package/src/trait.ts +238 -0
- package/README.md +0 -30
- package/lib/client.d.ts +0 -167
- package/lib/client.d.ts.map +0 -1
- package/lib/client.js +0 -659
- package/lib/client.js.map +0 -1
- package/lib/schemas.d.ts +0 -60
- package/lib/schemas.d.ts.map +0 -1
- package/lib/schemas.js +0 -79
- package/lib/schemas.js.map +0 -1
- package/lib/sensitive.d.ts +0 -71
- package/lib/sensitive.d.ts.map +0 -1
- package/lib/sensitive.js +0 -96
- package/lib/sensitive.js.map +0 -1
- package/lib/traits.d.ts +0 -421
- package/lib/traits.d.ts.map +0 -1
- package/lib/traits.js +0 -737
- package/lib/traits.js.map +0 -1
- package/src/client.ts +0 -1177
- package/src/schemas.ts +0 -128
- package/src/sensitive.ts +0 -119
- package/src/traits.ts +0 -996
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PURE annotation emitted before generated schema consts. A single
|
|
3
|
+
* `/*@__PURE__*/` — Rolldown 1.1+ warns on the `/*#__PURE__*/` form
|
|
4
|
+
* (distilled #374).
|
|
5
|
+
*/
|
|
6
|
+
export declare const PURE = "/*@__PURE__*/ ";
|
|
7
|
+
/** `export interface X { … }` (or the empty-body form). */
|
|
8
|
+
export declare const interfaceDecl: (name: string, fields: string[]) => string;
|
|
9
|
+
export interface SuspendConstOptions {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
/** The schema expression inside the suspend thunk. */
|
|
12
|
+
readonly expr: string;
|
|
13
|
+
/** PURE marker(s), e.g. `"/*@__PURE__*/ "`. Emitted verbatim before the expression. */
|
|
14
|
+
readonly pure?: string;
|
|
15
|
+
/** When set, `.annotate({ identifier: <name> })` is appended after the suspend. */
|
|
16
|
+
readonly annotateIdentifier?: boolean;
|
|
17
|
+
/** Extra annotation object source to use instead of the identifier default. */
|
|
18
|
+
readonly annotation?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Explicit thunk return type (`(): S.Schema<X> =>`) — used for shapes in
|
|
21
|
+
* dependency cycles to stop circular type inference.
|
|
22
|
+
*/
|
|
23
|
+
readonly thunkType?: string;
|
|
24
|
+
/** CF-style multiline body (`S.suspend(() =>\n<expr>,\n)`). */
|
|
25
|
+
readonly multiline?: boolean;
|
|
26
|
+
/** The cast target; defaults to `S.Schema<name>`. */
|
|
27
|
+
readonly castTo?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The `export const X = S.suspend(…) … as any as S.Schema<X>;` skeleton
|
|
31
|
+
* shared by both generators.
|
|
32
|
+
*/
|
|
33
|
+
export declare const suspendConst: (o: SuspendConstOptions) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Member-level lazy reference: `S.suspend(() => X).annotate({ identifier })`.
|
|
36
|
+
* The `typed` form adds an explicit `S.Schema<X>` thunk return type — used
|
|
37
|
+
* for references into dependency cycles to stop circular type inference.
|
|
38
|
+
*/
|
|
39
|
+
export declare const suspendRef: (name: string, typed?: boolean) => string;
|
|
40
|
+
export interface EnumDeclOptions {
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly values: readonly string[];
|
|
43
|
+
readonly pure?: string;
|
|
44
|
+
/** The schema const expression; both SDKs use `S.String` (open enums). */
|
|
45
|
+
readonly schemaExpr?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* String-union enum ALIAS: the spec's documented values as a CLOSED literal
|
|
49
|
+
* union (`type X = "a" | "b"`) — response readers match documented values
|
|
50
|
+
* exhaustively. INPUT references re-open the alias inline
|
|
51
|
+
* (`X | (string & {})`) so consumers can send tomorrow's values without an
|
|
52
|
+
* SDK update. The schema stays `S.String` in both directions (the
|
|
53
|
+
* protocols never validate enum membership, so undocumented wire values
|
|
54
|
+
* always pass through at runtime).
|
|
55
|
+
*/
|
|
56
|
+
export declare const enumDecl: (o: EnumDeclOptions) => string[];
|
|
57
|
+
export interface ErrorClassOptions {
|
|
58
|
+
readonly name: string;
|
|
59
|
+
/** The error tag; defaults to `name`. */
|
|
60
|
+
readonly tag?: string;
|
|
61
|
+
/** Field lines (` key: S.String,`). */
|
|
62
|
+
readonly fields: readonly string[];
|
|
63
|
+
/** Optional extra argument(s) after the fields object (annotations). */
|
|
64
|
+
readonly annotations?: string;
|
|
65
|
+
/** `.pipe(…)` suffix (e.g. category decorators). */
|
|
66
|
+
readonly pipes?: string;
|
|
67
|
+
/** Wrap the class expression (e.g. `T.applyErrorMatchers(<cls>, …)`). */
|
|
68
|
+
readonly wrap?: (cls: string) => string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `export class X extends /*@__PURE__*/ S.TaggedErrorClass<X>()("X", { … }) {}`
|
|
72
|
+
*
|
|
73
|
+
* The PURE markers are what make an unused error class droppable. A class
|
|
74
|
+
* whose heritage clause is an unannotated call can never be tree-shaken —
|
|
75
|
+
* the bundler has to assume the call has side effects — so a consumer
|
|
76
|
+
* importing one operation would retain every error class in the module
|
|
77
|
+
* (distilled #191).
|
|
78
|
+
*
|
|
79
|
+
* `wrap` needs its own marker as well as the inner one: a pure call's
|
|
80
|
+
* ARGUMENTS are still evaluated, so annotating only
|
|
81
|
+
* `T.applyErrorMatchers(S.TaggedErrorClass…(…), […])` leaves the inner call
|
|
82
|
+
* holding the class alive. Verified against esbuild in both directions.
|
|
83
|
+
*/
|
|
84
|
+
export declare const errorClass: (o: ErrorClassOptions) => string;
|
|
85
|
+
export interface OperationConstOptions {
|
|
86
|
+
/** The exported (usually lowerFirst) operation name. */
|
|
87
|
+
readonly exportName: string;
|
|
88
|
+
/** Full type annotation (e.g. `API.OperationMethod<A, B, E, R>`). */
|
|
89
|
+
readonly typeAnnotation: string;
|
|
90
|
+
/** `API.make` or `API.makePaginated` (with namespace prefix). */
|
|
91
|
+
readonly factory: string;
|
|
92
|
+
/** The config object source (including braces). */
|
|
93
|
+
readonly config: string;
|
|
94
|
+
/** Optional extra factory argument (e.g. a pagination strategy). */
|
|
95
|
+
readonly extraArg?: string;
|
|
96
|
+
readonly pure?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Widen the factory result to `any`, for annotations the factory's
|
|
99
|
+
* generic signature can't prove. The one case today: a paginated
|
|
100
|
+
* operation's `items` element type comes from the pagination trait's
|
|
101
|
+
* `items` PATH — a runtime string — so the factory can only infer the
|
|
102
|
+
* structural fallback while the annotation names the real element type.
|
|
103
|
+
*
|
|
104
|
+
* Unlike the schema consts' `as any as S.Schema<X>`, the target doesn't
|
|
105
|
+
* need restating here: the const carries its own annotation, which IS
|
|
106
|
+
* the assignment target, so a bare `as any` lands in the same place.
|
|
107
|
+
* Restating it would double every paginated operation's declaration —
|
|
108
|
+
* ~40k lines across the SDKs — for no added checking.
|
|
109
|
+
*/
|
|
110
|
+
readonly castToAnnotation?: boolean;
|
|
111
|
+
}
|
|
112
|
+
/** `export const op: T = API.make(() => ({ … }));` */
|
|
113
|
+
export declare const operationConst: (o: OperationConstOptions) => string;
|
|
114
|
+
export interface InterfaceFieldOptions {
|
|
115
|
+
readonly name: string;
|
|
116
|
+
readonly type: string;
|
|
117
|
+
readonly optional: boolean;
|
|
118
|
+
readonly doc?: string;
|
|
119
|
+
}
|
|
120
|
+
/** Interface field line(s): optional doc comment + ` name?: Type;`. */
|
|
121
|
+
export declare const interfaceField: (o: InterfaceFieldOptions) => string[];
|
|
122
|
+
/** `export type <Op>Error = A | B | <CommonErrors>;` */
|
|
123
|
+
export declare const errorUnionAlias: (opName: string, errorNames: readonly string[], commonRef: string) => string;
|
|
124
|
+
/** Namespaced barrel: `export * as name from "./file.ts";` per entry. */
|
|
125
|
+
export declare const barrel: (header: string, entries: ReadonlyArray<{
|
|
126
|
+
name: string;
|
|
127
|
+
path: string;
|
|
128
|
+
}>) => string;
|
|
129
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared emission idioms for the SDK generators (dev-time only).
|
|
3
|
+
*
|
|
4
|
+
* Both SDK generators emit the same compile-time-performance pattern
|
|
5
|
+
* (ported from distilled PR #360):
|
|
6
|
+
*
|
|
7
|
+
* export interface X { … } // hand-emitted type
|
|
8
|
+
* export const X = S.suspend(() => S.Struct({…}))
|
|
9
|
+
* .annotate({ identifier: "X" })
|
|
10
|
+
* as any as S.Schema<X>; // no inference needed
|
|
11
|
+
*
|
|
12
|
+
* plus closed-alias string-union enums, `S.TaggedErrorClass` error classes, and
|
|
13
|
+
* `API.make(() => ({ … }))` operation consts. The helpers here own those
|
|
14
|
+
* shared skeletons; providers own the content strings (member pipes, trait
|
|
15
|
+
* calls, config fields). Emitted output is normalized by oxfmt afterwards,
|
|
16
|
+
* so helpers emit canonical token streams rather than matching historical
|
|
17
|
+
* whitespace.
|
|
18
|
+
*/
|
|
19
|
+
import { q } from "./naming.js";
|
|
20
|
+
/**
|
|
21
|
+
* The PURE annotation emitted before generated schema consts. A single
|
|
22
|
+
* `/*@__PURE__*/` — Rolldown 1.1+ warns on the `/*#__PURE__*/` form
|
|
23
|
+
* (distilled #374).
|
|
24
|
+
*/
|
|
25
|
+
export const PURE = "/*@__PURE__*/ ";
|
|
26
|
+
/** `export interface X { … }` (or the empty-body form). */
|
|
27
|
+
export const interfaceDecl = (name, fields) => fields.length
|
|
28
|
+
? `export interface ${name} {\n${fields.join("\n")}\n}`
|
|
29
|
+
: `export interface ${name} {}`;
|
|
30
|
+
/**
|
|
31
|
+
* The `export const X = S.suspend(…) … as any as S.Schema<X>;` skeleton
|
|
32
|
+
* shared by both generators.
|
|
33
|
+
*/
|
|
34
|
+
export const suspendConst = (o) => {
|
|
35
|
+
const cast = o.castTo ?? `S.Schema<${o.name}>`;
|
|
36
|
+
const thunk = o.thunkType ? `(): ${o.thunkType} =>` : `() =>`;
|
|
37
|
+
const suspend = o.multiline
|
|
38
|
+
? `S.suspend(${thunk}\n${o.expr},\n)`
|
|
39
|
+
: `S.suspend(${thunk} ${o.expr})`;
|
|
40
|
+
const annotate = o.annotation
|
|
41
|
+
? `.annotate(${o.annotation})`
|
|
42
|
+
: o.annotateIdentifier
|
|
43
|
+
? `.annotate({ identifier: ${q(o.name)} })`
|
|
44
|
+
: "";
|
|
45
|
+
return `export const ${o.name} = ${o.pure ?? ""}${suspend}${annotate} as any as ${cast};\n`;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Member-level lazy reference: `S.suspend(() => X).annotate({ identifier })`.
|
|
49
|
+
* The `typed` form adds an explicit `S.Schema<X>` thunk return type — used
|
|
50
|
+
* for references into dependency cycles to stop circular type inference.
|
|
51
|
+
*/
|
|
52
|
+
export const suspendRef = (name, typed = false) => typed
|
|
53
|
+
? `S.suspend((): S.Schema<${name}> => ${name}).annotate({ identifier: ${q(name)} })`
|
|
54
|
+
: `S.suspend(() => ${name}).annotate({ identifier: ${q(name)} })`;
|
|
55
|
+
/**
|
|
56
|
+
* String-union enum ALIAS: the spec's documented values as a CLOSED literal
|
|
57
|
+
* union (`type X = "a" | "b"`) — response readers match documented values
|
|
58
|
+
* exhaustively. INPUT references re-open the alias inline
|
|
59
|
+
* (`X | (string & {})`) so consumers can send tomorrow's values without an
|
|
60
|
+
* SDK update. The schema stays `S.String` in both directions (the
|
|
61
|
+
* protocols never validate enum membership, so undocumented wire values
|
|
62
|
+
* always pass through at runtime).
|
|
63
|
+
*/
|
|
64
|
+
export const enumDecl = (o) => {
|
|
65
|
+
const union = o.values.length ? o.values.map(q).join(" | ") : "string";
|
|
66
|
+
return [
|
|
67
|
+
`export type ${o.name} = ${union};`,
|
|
68
|
+
`export const ${o.name} = ${o.pure ?? ""}${o.schemaExpr ?? "S.String"};\n`,
|
|
69
|
+
];
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* `export class X extends /*@__PURE__*/ S.TaggedErrorClass<X>()("X", { … }) {}`
|
|
73
|
+
*
|
|
74
|
+
* The PURE markers are what make an unused error class droppable. A class
|
|
75
|
+
* whose heritage clause is an unannotated call can never be tree-shaken —
|
|
76
|
+
* the bundler has to assume the call has side effects — so a consumer
|
|
77
|
+
* importing one operation would retain every error class in the module
|
|
78
|
+
* (distilled #191).
|
|
79
|
+
*
|
|
80
|
+
* `wrap` needs its own marker as well as the inner one: a pure call's
|
|
81
|
+
* ARGUMENTS are still evaluated, so annotating only
|
|
82
|
+
* `T.applyErrorMatchers(S.TaggedErrorClass…(…), […])` leaves the inner call
|
|
83
|
+
* holding the class alive. Verified against esbuild in both directions.
|
|
84
|
+
*/
|
|
85
|
+
export const errorClass = (o) => {
|
|
86
|
+
const annotations = o.annotations ? `,\n${o.annotations}` : "";
|
|
87
|
+
const cls = `${PURE}S.TaggedErrorClass<${o.name}>()(${q(o.tag ?? o.name)}, {\n${o.fields.join("\n")}\n}${annotations})${o.pipes ?? ""}`;
|
|
88
|
+
const body = o.wrap ? `${PURE}${o.wrap(cls)}` : cls;
|
|
89
|
+
return `export class ${o.name} extends ${body} {}\n`;
|
|
90
|
+
};
|
|
91
|
+
/** `export const op: T = API.make(() => ({ … }));` */
|
|
92
|
+
export const operationConst = (o) => `export const ${o.exportName}: ${o.typeAnnotation} = ${o.pure ?? ""}${o.factory}(() => (${o.config})${o.extraArg ? `, ${o.extraArg}` : ""})${o.castToAnnotation ? ` as any` : ""};\n`;
|
|
93
|
+
import { tsKey } from "./naming.js";
|
|
94
|
+
/** Interface field line(s): optional doc comment + ` name?: Type;`. */
|
|
95
|
+
export const interfaceField = (o) => [
|
|
96
|
+
...(o.doc ? [` /** ${o.doc} */`] : []),
|
|
97
|
+
` ${tsKey(o.name)}${o.optional ? "?" : ""}: ${o.type};`,
|
|
98
|
+
];
|
|
99
|
+
/** `export type <Op>Error = A | B | <CommonErrors>;` */
|
|
100
|
+
export const errorUnionAlias = (opName, errorNames, commonRef) => `export type ${opName}Error = ${[...errorNames, commonRef].join(" | ")};`;
|
|
101
|
+
/** Namespaced barrel: `export * as name from "./file.ts";` per entry. */
|
|
102
|
+
export const barrel = (header, entries) => header +
|
|
103
|
+
entries.map((e) => `export * as ${e.name} from ${q(e.path)};`).join("\n") +
|
|
104
|
+
"\n";
|
|
105
|
+
//# sourceMappingURL=emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/codegen/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-generation formatting (dev-time only).
|
|
3
|
+
*
|
|
4
|
+
* The emitters produce a canonical token stream, not formatted source, so
|
|
5
|
+
* every generator formats what it wrote before finishing. Without it a
|
|
6
|
+
* generate run leaves the whole output directory dirty against the committed
|
|
7
|
+
* (formatted) files, and a real regression is indistinguishable from
|
|
8
|
+
* whitespace in the diff.
|
|
9
|
+
*
|
|
10
|
+
* Lives here so the shared {@link runGeneratorCli} and the providers with
|
|
11
|
+
* their own pipelines run the identical step.
|
|
12
|
+
*/
|
|
13
|
+
import { Effect } from "effect";
|
|
14
|
+
/** Run a dev-time tool, failing the generate run if it does. */
|
|
15
|
+
export declare const runTool: (argv: readonly string[]) => Effect.Effect<void, never, never>;
|
|
16
|
+
/** Format a generated directory in place. */
|
|
17
|
+
export declare const formatGenerated: (dir: string) => Effect.Effect<void, never, never>;
|
|
18
|
+
/**
|
|
19
|
+
* Lint-fix then format. `oxlint --fix` can leave its rewrites unformatted,
|
|
20
|
+
* so the formatter has to run after it, not before.
|
|
21
|
+
*/
|
|
22
|
+
export declare const lintAndFormatGenerated: (dir: string) => Effect.Effect<void, never, never>;
|
|
23
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/codegen/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAW,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzC,gEAAgE;AAChE,eAAO,MAAM,OAAO,SACZ,SAAS,MAAM,EAAE,KACtB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAYhC,CAAC;AAEJ,6CAA6C;AAC7C,eAAO,MAAM,eAAe,QAAS,MAAM,sCAGxC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,sCAK/C,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-generation formatting (dev-time only).
|
|
3
|
+
*
|
|
4
|
+
* The emitters produce a canonical token stream, not formatted source, so
|
|
5
|
+
* every generator formats what it wrote before finishing. Without it a
|
|
6
|
+
* generate run leaves the whole output directory dirty against the committed
|
|
7
|
+
* (formatted) files, and a real regression is indistinguishable from
|
|
8
|
+
* whitespace in the diff.
|
|
9
|
+
*
|
|
10
|
+
* Lives here so the shared {@link runGeneratorCli} and the providers with
|
|
11
|
+
* their own pipelines run the identical step.
|
|
12
|
+
*/
|
|
13
|
+
import { Console, Effect } from "effect";
|
|
14
|
+
/** Run a dev-time tool, failing the generate run if it does. */
|
|
15
|
+
export const runTool = (argv) => Effect.tryPromise({
|
|
16
|
+
try: () => Bun.spawn([...argv], { stdout: "inherit", stderr: "inherit" }).exited,
|
|
17
|
+
catch: (cause) => new Error(`${argv[0]} failed to start: ${cause}`),
|
|
18
|
+
}).pipe(Effect.flatMap((code) => code === 0
|
|
19
|
+
? Effect.void
|
|
20
|
+
: Effect.die(new Error(`${argv.join(" ")} exited with ${code}`))), Effect.catchCause((cause) => Effect.die(cause)));
|
|
21
|
+
/** Format a generated directory in place. */
|
|
22
|
+
export const formatGenerated = (dir) => Effect.flatMap(Console.log(`\n🧹 Formatting ${dir}`), () => runTool(["bunx", "oxfmt", dir]));
|
|
23
|
+
/**
|
|
24
|
+
* Lint-fix then format. `oxlint --fix` can leave its rewrites unformatted,
|
|
25
|
+
* so the formatter has to run after it, not before.
|
|
26
|
+
*/
|
|
27
|
+
export const lintAndFormatGenerated = (dir) => Effect.flatMap(Console.log(`\n🧹 Linting and formatting ${dir}`), () => Effect.flatMap(runTool(["bunx", "oxlint", "--fix", dir]), () => runTool(["bunx", "oxfmt", dir])));
|
|
28
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/codegen/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzC,gEAAgE;AAChE,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,IAAuB,EACY,EAAE,CACrC,MAAM,CAAC,UAAU,CAAC;IAChB,GAAG,EAAE,GAAG,EAAE,CACR,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM;IACvE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,qBAAqB,KAAK,EAAE,CAAC;CACpE,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,IAAI,KAAK,CAAC;IACR,CAAC,CAAC,MAAM,CAAC,IAAI;IACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,CACnE,EACD,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAChD,CAAC;AAEJ,6CAA6C;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,EAAE,CAC7C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CACzD,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAChC,CAAC;AAEJ;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAW,EAAE,EAAE,CACpD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CACrE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAC7D,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAChC,CACF,CAAC"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generic smithy→SDK service generator (dev-time only).
|
|
3
|
+
*
|
|
4
|
+
* One driver compiles a Smithy JSON model into an Effect SDK service module.
|
|
5
|
+
* Everything provider-specific arrives through {@link SdkSpec}: import
|
|
6
|
+
* header, trait vocabulary (which trait ids mean payload/file/nullable/…),
|
|
7
|
+
* the `T.*` pipe expressions to emit for each binding, how operations are
|
|
8
|
+
* declared (protocol/retry/error names), and naming policies. The driver
|
|
9
|
+
* owns the pipeline: operation discovery, reachability, topological order,
|
|
10
|
+
* schema/interface emission, error classes, pagination validation, and
|
|
11
|
+
* operation consts.
|
|
12
|
+
*
|
|
13
|
+
* A provider's `scripts/generate.ts` reduces to: load models (its own
|
|
14
|
+
* pipeline — docs-derived specs, patches, …), define its {@link SdkSpec},
|
|
15
|
+
* call {@link generateService} per model, write files.
|
|
16
|
+
*/
|
|
17
|
+
import { local, q, tsKey, upperFirst } from "./naming.ts";
|
|
18
|
+
import { type ShapeMap } from "./graph.ts";
|
|
19
|
+
import { errorUnionAlias, operationConst } from "./emit.ts";
|
|
20
|
+
import { type OpEntry } from "./operations.ts";
|
|
21
|
+
/**
|
|
22
|
+
* Error categories, derived from the STANDARD Smithy error traits.
|
|
23
|
+
*
|
|
24
|
+
* `smithy.api#httpError` and `smithy.api#retryable` are how every Smithy
|
|
25
|
+
* model — AWS's included — says what kind of failure an error is. The
|
|
26
|
+
* categories the runtime acts on (`core/category.ts`, and `isTransientError`
|
|
27
|
+
* in `core/retry.ts`) are a reading of those two traits, so the reading
|
|
28
|
+
* belongs here, once, for every provider.
|
|
29
|
+
*
|
|
30
|
+
* A model that wants its errors classified states the status the API
|
|
31
|
+
* actually returns:
|
|
32
|
+
*
|
|
33
|
+
* "traits": { "smithy.api#error": "client", "smithy.api#httpError": 404 }
|
|
34
|
+
*
|
|
35
|
+
* and the error class is emitted with `.pipe(C.withNotFoundError)`. A model
|
|
36
|
+
* with no `httpError` gets no categories — the same as today.
|
|
37
|
+
*/
|
|
38
|
+
export declare const errorCategories: (traits: Record<string, any> | undefined,
|
|
39
|
+
/** Categories a provider knows that the traits don't say (AWS's spec file). */
|
|
40
|
+
extra?: readonly string[]) => string[];
|
|
41
|
+
/** A member's resolved binding. The four generic kinds plus provider extras. */
|
|
42
|
+
export type MemberBinding = "label" | "query" | "header" | "body" | (string & {});
|
|
43
|
+
export interface EmittedMember {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly tsName: string;
|
|
46
|
+
readonly wire: string;
|
|
47
|
+
readonly target: string;
|
|
48
|
+
readonly binding: MemberBinding;
|
|
49
|
+
readonly required: boolean;
|
|
50
|
+
readonly nullable: boolean;
|
|
51
|
+
readonly doc: string | undefined;
|
|
52
|
+
readonly traits: Record<string, any>;
|
|
53
|
+
}
|
|
54
|
+
export interface PaginationProfile {
|
|
55
|
+
/** Protocol const for paginated ops. Defaults to operationDecl.protocol. */
|
|
56
|
+
readonly protocol?: string;
|
|
57
|
+
/** Strategy expression passed as makePaginated's second argument. */
|
|
58
|
+
readonly strategy?: string;
|
|
59
|
+
/** Items path fallback when the trait omits `items`. */
|
|
60
|
+
readonly itemsFallback: string;
|
|
61
|
+
/** Output names accepted even when not modeled (delivered by the protocol). */
|
|
62
|
+
readonly syntheticOutputs?: readonly string[];
|
|
63
|
+
/**
|
|
64
|
+
* Extra interface field + struct member appended to paginated outputs
|
|
65
|
+
* that don't already model them (what the protocol delivers beyond the
|
|
66
|
+
* modeled shape — e.g. cloudflare's `resultInfo` from the envelope's
|
|
67
|
+
* `result_info`). `imports` are pulled from the pagination module in the
|
|
68
|
+
* header.
|
|
69
|
+
*/
|
|
70
|
+
readonly injectOutputMember?: {
|
|
71
|
+
readonly tsName: string;
|
|
72
|
+
readonly interfaceLines: readonly string[];
|
|
73
|
+
readonly structLine: string;
|
|
74
|
+
readonly imports?: readonly string[];
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface OperationEmit {
|
|
78
|
+
readonly op: OpEntry;
|
|
79
|
+
readonly opName: string;
|
|
80
|
+
readonly exportName: string;
|
|
81
|
+
readonly inputName: string;
|
|
82
|
+
readonly outputName: string;
|
|
83
|
+
/**
|
|
84
|
+
* The output as a TS type and as a schema expression. These differ from
|
|
85
|
+
* {@link outputName} when the operation's output IS a prelude shape
|
|
86
|
+
* (e.g. stripe's freeform `smithy.api#Document` responses): the bare
|
|
87
|
+
* local name isn't declared in the module, so it must resolve through
|
|
88
|
+
* the prelude maps (`unknown` / `S.Unknown`) instead.
|
|
89
|
+
*/
|
|
90
|
+
readonly outputTsType: string;
|
|
91
|
+
readonly outputSchema: string;
|
|
92
|
+
/** Declared error class names present in the model. */
|
|
93
|
+
readonly errorNames: readonly string[];
|
|
94
|
+
readonly doc: string | undefined;
|
|
95
|
+
/** The validated pagination trait, when the op paginates. */
|
|
96
|
+
readonly pagination: unknown | undefined;
|
|
97
|
+
}
|
|
98
|
+
export interface SdkSpec {
|
|
99
|
+
/** Namespace fallback for models with no operations. Default `"smithy.unknown"`. */
|
|
100
|
+
readonly namespaceFallback?: string;
|
|
101
|
+
/** PURE marker before schema consts. Default: the shared single marker. */
|
|
102
|
+
readonly pure?: string;
|
|
103
|
+
/** Prelude scalar → schema expression map. Default {@link JSON_PRELUDE}. */
|
|
104
|
+
readonly prelude?: Record<string, string>;
|
|
105
|
+
/** Prelude scalar → TS type map. Default {@link TS_JSON_PRELUDE}. */
|
|
106
|
+
readonly tsPrelude?: Record<string, string>;
|
|
107
|
+
/** Wire member name → TS-facing name. Default: identity. */
|
|
108
|
+
readonly memberName?: (name: string) => string;
|
|
109
|
+
/** Operation shape name → exported const name. Default: lowerFirst. */
|
|
110
|
+
readonly opExportName?: (name: string) => string;
|
|
111
|
+
/**
|
|
112
|
+
* Emit the one-line smithy doc comment above shapes and error classes.
|
|
113
|
+
* Default true. AWS turns this off — its models carry multi-kilobyte HTML
|
|
114
|
+
* docs per shape and the SDK only surfaces operation-level docs.
|
|
115
|
+
*/
|
|
116
|
+
readonly shapeDocs?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Extra reachability roots beyond the operations' I/O shapes. AWS seeds
|
|
119
|
+
* the error shapes here so their member targets are emitted (error class
|
|
120
|
+
* fields reference schema consts); the error shapes themselves are still
|
|
121
|
+
* emitted as error classes, not schemas.
|
|
122
|
+
*/
|
|
123
|
+
readonly extraRoots?: (selected: readonly OpEntry[], shapes: ShapeMap) => Iterable<string>;
|
|
124
|
+
/**
|
|
125
|
+
* Provider member bindings as data, checked in order between the generic
|
|
126
|
+
* header binding and `smithy.api#httpPayload`. The driver's cascade:
|
|
127
|
+
* label → query → header → extraBindings → rawBody (httpPayload) → body.
|
|
128
|
+
*
|
|
129
|
+
* `pipe` is emitted for the member; `tsType` overrides its interface
|
|
130
|
+
* type (e.g. file uploads → `(File | Blob)[]`).
|
|
131
|
+
*/
|
|
132
|
+
readonly extraBindings?: ReadonlyArray<{
|
|
133
|
+
readonly trait: string;
|
|
134
|
+
readonly binding: MemberBinding;
|
|
135
|
+
readonly pipe: string;
|
|
136
|
+
readonly tsType?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Bare-payload form: when this binding is the sole member of a
|
|
139
|
+
* (non-paginated) output structure, the whole response IS that
|
|
140
|
+
* member's value — the driver emits the member's type directly and
|
|
141
|
+
* pipes the schema through this root marker for the protocol.
|
|
142
|
+
*/
|
|
143
|
+
readonly rootPipe?: string;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Which wire-name rule a binding follows. Defaults: the three generic
|
|
147
|
+
* kinds map to themselves, everything else to `"other"` (jsonName).
|
|
148
|
+
*/
|
|
149
|
+
readonly wireKind?: (binding: MemberBinding) => "label" | "query" | "header" | "other";
|
|
150
|
+
/** Trait id marking a member nullable (`S.NullOr` + `| null`). */
|
|
151
|
+
readonly nullableTrait?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Blanket-nullable optionals: every optional body member types and
|
|
154
|
+
* decodes as `X | null` in addition to being omittable (`?: X | null`,
|
|
155
|
+
* `S.optional(S.NullOr(X))`). The cloudflare docs pipeline sets this —
|
|
156
|
+
* the v4 API freely returns explicit nulls for absent optional fields,
|
|
157
|
+
* and the v0 SDK surface modeled every optional that way.
|
|
158
|
+
*/
|
|
159
|
+
readonly optionalsNullable?: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Member traits emitted as pipes when present: trait id → pipe builder
|
|
162
|
+
* name in the SDK's traits module. The trait's value is JSON-inlined as
|
|
163
|
+
* the argument (e.g. `"…#keyDictionary": "T.KeyDictionary"` →
|
|
164
|
+
* `T.KeyDictionary({…})`).
|
|
165
|
+
*/
|
|
166
|
+
readonly memberTraitPipes?: Readonly<Record<string, string>>;
|
|
167
|
+
/**
|
|
168
|
+
* Extra schema pipes appended after the generic ones, for anything the
|
|
169
|
+
* data tables can't express. The driver emits `T.Label/T.Query/T.Header`
|
|
170
|
+
* (wire-aware), `T.HttpBody()` for rawBody, and `T.Body(wire)` renames —
|
|
171
|
+
* the SDK's traits module must export those core builders under these
|
|
172
|
+
* names.
|
|
173
|
+
*/
|
|
174
|
+
readonly memberExtraPipes?: (m: EmittedMember) => string[];
|
|
175
|
+
/** Full override of member pipe emission (rarely needed). */
|
|
176
|
+
readonly memberPipes?: (m: EmittedMember) => string[];
|
|
177
|
+
/** Function override for member TS types beyond the binding table. */
|
|
178
|
+
readonly memberTsType?: (m: EmittedMember, tsRef: (target: string) => string) => string | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Struct-level pipes for a shape (after the member struct): the http
|
|
181
|
+
* trait on op inputs, service-wide key-dictionary stamping, etc.
|
|
182
|
+
*/
|
|
183
|
+
readonly structPipes?: (ctx: {
|
|
184
|
+
readonly id: string;
|
|
185
|
+
readonly isOpIo: boolean;
|
|
186
|
+
readonly httpTrait: unknown | undefined;
|
|
187
|
+
}) => string[];
|
|
188
|
+
/**
|
|
189
|
+
* Pagination profiles. A profile is the codegen-side description of one
|
|
190
|
+
* paginated wire variant: the Protocol const that decodes it, the
|
|
191
|
+
* strategy passed to makePaginated, the trait-validation rules, and any
|
|
192
|
+
* output member the protocol delivers beyond the modeled shape. SDKs
|
|
193
|
+
* with several pagination styles declare several profiles and select
|
|
194
|
+
* per-op via {@link SdkSpec.paginationProfileFor}.
|
|
195
|
+
*/
|
|
196
|
+
readonly paginationProfiles?: Readonly<Record<string, PaginationProfile>>;
|
|
197
|
+
/**
|
|
198
|
+
* Select the profile for a paginated op (from its `smithy.api#paginated`
|
|
199
|
+
* trait / shape). Default: the sole declared profile; with several
|
|
200
|
+
* profiles this becomes required for ops to paginate.
|
|
201
|
+
*/
|
|
202
|
+
readonly paginationProfileFor?: (trait: any, op: OpEntry) => string | undefined;
|
|
203
|
+
/**
|
|
204
|
+
* Service-wide fallback key dictionary stamped on op I/O roots (emitted
|
|
205
|
+
* as a `KEY_DICTIONARY` header const + `T.KeyDictionary(KEY_DICTIONARY)`
|
|
206
|
+
* root pipe). `doc` is the const's doc comment. An entry may list several
|
|
207
|
+
* wire spellings (first = canonical encode name; decode accepts all).
|
|
208
|
+
*/
|
|
209
|
+
readonly rootKeyDictionary?: {
|
|
210
|
+
readonly dict: Record<string, string | ReadonlyArray<string>>;
|
|
211
|
+
readonly doc: string;
|
|
212
|
+
};
|
|
213
|
+
/** Banner suffix: `AUTO-GENERATED by scripts/generate.ts from <note>`. */
|
|
214
|
+
readonly sourceNote?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Operation aliases: re-export the canonical op (and its
|
|
217
|
+
* Request/Response/Error types) under each alias name. Skipped when the
|
|
218
|
+
* target wasn't emitted or the alias name is taken.
|
|
219
|
+
*/
|
|
220
|
+
readonly opAliases?: ReadonlyArray<{
|
|
221
|
+
readonly alias: string;
|
|
222
|
+
readonly target: string;
|
|
223
|
+
}>;
|
|
224
|
+
/**
|
|
225
|
+
* Full shape-emission override, checked before the driver's own shape
|
|
226
|
+
* handling. Return the emitted lines to own a shape (e.g. AWS's
|
|
227
|
+
* newtypes, structural unions, event streams), or undefined to let the
|
|
228
|
+
* driver emit it. `selfIdx` is the shape's position in emission order
|
|
229
|
+
* for forward-ref decisions.
|
|
230
|
+
*/
|
|
231
|
+
readonly shapeOverride?: (ctx: {
|
|
232
|
+
readonly id: string;
|
|
233
|
+
readonly def: any;
|
|
234
|
+
readonly name: string;
|
|
235
|
+
readonly selfIdx: number;
|
|
236
|
+
readonly ref: (target: string, selfIdx: number) => string;
|
|
237
|
+
readonly tsRef: (target: string) => string;
|
|
238
|
+
readonly members: (d: any) => EmittedMember[];
|
|
239
|
+
}) => string[] | undefined;
|
|
240
|
+
/**
|
|
241
|
+
* Union emission style. `"opaque-cases"`: the TS type is the case union
|
|
242
|
+
* and the schema is `S.Unknown.pipe(T.UnionCases([...case key sets]))` —
|
|
243
|
+
* the protocol discriminates by key-set at decode time (for APIs that
|
|
244
|
+
* return every case's keys with nulls, like Cloudflare's).
|
|
245
|
+
*/
|
|
246
|
+
readonly unionStyle?: "opaque-cases";
|
|
247
|
+
/** Full override of union emission. */
|
|
248
|
+
readonly union?: (ctx: {
|
|
249
|
+
readonly name: string;
|
|
250
|
+
readonly caseTargets: readonly string[];
|
|
251
|
+
readonly caseKeys: readonly (readonly string[])[];
|
|
252
|
+
readonly tsRef: (target: string) => string;
|
|
253
|
+
}) => string[];
|
|
254
|
+
/**
|
|
255
|
+
* Trait id carrying error matchers: when present on an error shape, the
|
|
256
|
+
* class is wrapped in `T.applyErrorMatchers(<cls>, <trait value>)`.
|
|
257
|
+
*/
|
|
258
|
+
readonly errorMatchersTrait?: string;
|
|
259
|
+
/** Error-class emission details. All optional. */
|
|
260
|
+
readonly errors?: {
|
|
261
|
+
/**
|
|
262
|
+
* Full override of one error class's emission (mirrors shapeOverride):
|
|
263
|
+
* return the emitted lines to own the error, or undefined to fall back
|
|
264
|
+
* to the driver's field/wrap-based emission.
|
|
265
|
+
*/
|
|
266
|
+
readonly override?: (ctx: {
|
|
267
|
+
readonly id: string;
|
|
268
|
+
readonly def: any;
|
|
269
|
+
readonly name: string;
|
|
270
|
+
}) => string[] | undefined;
|
|
271
|
+
/**
|
|
272
|
+
* Field lines used when the error shape declares no members.
|
|
273
|
+
* Default: `code` (integer) + `message` (string) — the common REST
|
|
274
|
+
* error envelope.
|
|
275
|
+
*/
|
|
276
|
+
readonly defaultFields?: (prelude: Record<string, string>) => string[];
|
|
277
|
+
/** Field line for a declared member. Default: prelude-mapped schema. */
|
|
278
|
+
readonly field?: (name: string, target: string) => string;
|
|
279
|
+
/** Optional wrapper (e.g. matcher application) from the shape's traits. */
|
|
280
|
+
readonly wrap?: (traits: Record<string, any>) => ((cls: string) => string) | undefined;
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Declarative operation emission — the names the op consts are built
|
|
284
|
+
* from. `operation` overrides this entirely when a provider needs full
|
|
285
|
+
* control of the emitted shape.
|
|
286
|
+
*/
|
|
287
|
+
readonly operationDecl?: {
|
|
288
|
+
/** Requirements type in the OperationMethod annotation. */
|
|
289
|
+
readonly contextType: string;
|
|
290
|
+
/** Base of the per-op error union alias (e.g. `CloudflareOpError`). */
|
|
291
|
+
readonly commonErrorType: string;
|
|
292
|
+
/** Error classes appended to every op's `errors: [...]` list. */
|
|
293
|
+
readonly commonErrorClasses: readonly string[];
|
|
294
|
+
readonly protocol: string;
|
|
295
|
+
/** The retry tag expression (e.g. `Retry.Retry`). */
|
|
296
|
+
readonly retry: string;
|
|
297
|
+
/**
|
|
298
|
+
* Extra config lines inserted before the pagination entry (e.g. AWS's
|
|
299
|
+
* `operationName` and `endpointHostPrefix`).
|
|
300
|
+
*/
|
|
301
|
+
readonly extraConfig?: (ctx: OperationEmit) => string[];
|
|
302
|
+
};
|
|
303
|
+
/** Full override of operation const emission. */
|
|
304
|
+
readonly operation?: (ctx: OperationEmit) => string;
|
|
305
|
+
/**
|
|
306
|
+
* Module header override. The default builds the banner + imports from
|
|
307
|
+
* {@link SdkSpec.operationDecl} names and the conventional module layout
|
|
308
|
+
* (`../traits.ts`, `../protocol.ts`, `../pagination.ts`, `../errors.ts`,
|
|
309
|
+
* `../retry.ts`), re-exports the op error/context types, and emits the
|
|
310
|
+
* `KEY_DICTIONARY` const when {@link SdkSpec.rootKeyDictionary} is set.
|
|
311
|
+
*/
|
|
312
|
+
readonly header?: (ctx: {
|
|
313
|
+
readonly hasPaginated: boolean;
|
|
314
|
+
readonly model: any;
|
|
315
|
+
}) => string;
|
|
316
|
+
/** Final pass over the assembled module (e.g. pruning unused imports). */
|
|
317
|
+
readonly postProcess?: (code: string) => string;
|
|
318
|
+
/**
|
|
319
|
+
* Trailing sections after operations (e.g. route-alias re-exports).
|
|
320
|
+
* Receives the set of emitted op export names (mutable — additions are
|
|
321
|
+
* visible to subsequent alias checks).
|
|
322
|
+
*/
|
|
323
|
+
readonly footer?: (ctx: {
|
|
324
|
+
readonly emittedOps: Set<string>;
|
|
325
|
+
}) => string[];
|
|
326
|
+
}
|
|
327
|
+
export interface GeneratedService {
|
|
328
|
+
code: string;
|
|
329
|
+
operations: number;
|
|
330
|
+
}
|
|
331
|
+
/** Compile one Smithy model into a service module. */
|
|
332
|
+
export declare const generateService: (model: any, spec: SdkSpec) => GeneratedService;
|
|
333
|
+
export { errorUnionAlias, operationConst, upperFirst, tsKey, q, local };
|
|
334
|
+
//# sourceMappingURL=generator.d.ts.map
|