@stripe/extensibility-sdk 0.22.4
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/LICENSE.md +19 -0
- package/dist/config-values/generate.cjs +262 -0
- package/dist/config-values/generate.d.ts +38 -0
- package/dist/config-values/generate.d.ts.map +1 -0
- package/dist/config-values/generate.js +232 -0
- package/dist/config-values/parse.d.ts +87 -0
- package/dist/config-values/parse.d.ts.map +1 -0
- package/dist/extensibility-sdk-alpha.d.ts +542 -0
- package/dist/extensibility-sdk-beta.d.ts +542 -0
- package/dist/extensibility-sdk-config-values-alpha.d.ts +27 -0
- package/dist/extensibility-sdk-config-values-beta.d.ts +27 -0
- package/dist/extensibility-sdk-config-values-internal.d.ts +118 -0
- package/dist/extensibility-sdk-config-values-public.d.ts +27 -0
- package/dist/extensibility-sdk-extensions-alpha.d.ts +1592 -0
- package/dist/extensibility-sdk-extensions-beta.d.ts +1592 -0
- package/dist/extensibility-sdk-extensions-internal.d.ts +1655 -0
- package/dist/extensibility-sdk-extensions-public.d.ts +1592 -0
- package/dist/extensibility-sdk-internal-alpha.d.ts +9 -0
- package/dist/extensibility-sdk-internal-beta.d.ts +9 -0
- package/dist/extensibility-sdk-internal-internal.d.ts +23 -0
- package/dist/extensibility-sdk-internal-public.d.ts +9 -0
- package/dist/extensibility-sdk-internal.d.ts +915 -0
- package/dist/extensibility-sdk-jsonschema-alpha.d.ts +3 -0
- package/dist/extensibility-sdk-jsonschema-beta.d.ts +3 -0
- package/dist/extensibility-sdk-jsonschema-internal.d.ts +15 -0
- package/dist/extensibility-sdk-jsonschema-public.d.ts +3 -0
- package/dist/extensibility-sdk-public.d.ts +542 -0
- package/dist/extensibility-sdk-stdlib-alpha.d.ts +531 -0
- package/dist/extensibility-sdk-stdlib-beta.d.ts +531 -0
- package/dist/extensibility-sdk-stdlib-internal.d.ts +904 -0
- package/dist/extensibility-sdk-stdlib-public.d.ts +531 -0
- package/dist/extensions/billing/bill/discount_calculation.d.ts +226 -0
- package/dist/extensions/billing/bill/discount_calculation.d.ts.map +1 -0
- package/dist/extensions/billing/bill/index.d.ts +2 -0
- package/dist/extensions/billing/bill/index.d.ts.map +1 -0
- package/dist/extensions/billing/customer_balance_application.d.ts +82 -0
- package/dist/extensions/billing/customer_balance_application.d.ts.map +1 -0
- package/dist/extensions/billing/index.d.ts +8 -0
- package/dist/extensions/billing/index.d.ts.map +1 -0
- package/dist/extensions/billing/invoice_collection_setting.d.ts +117 -0
- package/dist/extensions/billing/invoice_collection_setting.d.ts.map +1 -0
- package/dist/extensions/billing/prorations.d.ts +222 -0
- package/dist/extensions/billing/prorations.d.ts.map +1 -0
- package/dist/extensions/billing/recurring_billing_item_handling.d.ts +326 -0
- package/dist/extensions/billing/recurring_billing_item_handling.d.ts.map +1 -0
- package/dist/extensions/billing/types.d.ts +33 -0
- package/dist/extensions/billing/types.d.ts.map +1 -0
- package/dist/extensions/context.d.ts +9 -0
- package/dist/extensions/context.d.ts.map +1 -0
- package/dist/extensions/core/index.d.ts +3 -0
- package/dist/extensions/core/index.d.ts.map +1 -0
- package/dist/extensions/core/workflows/custom_action.d.ts +142 -0
- package/dist/extensions/core/workflows/custom_action.d.ts.map +1 -0
- package/dist/extensions/core/workflows/index.d.ts +2 -0
- package/dist/extensions/core/workflows/index.d.ts.map +1 -0
- package/dist/extensions/extend/index.d.ts +3 -0
- package/dist/extensions/extend/index.d.ts.map +1 -0
- package/dist/extensions/extend/workflows/custom_action.d.ts +142 -0
- package/dist/extensions/extend/workflows/custom_action.d.ts.map +1 -0
- package/dist/extensions/extend/workflows/index.d.ts +2 -0
- package/dist/extensions/extend/workflows/index.d.ts.map +1 -0
- package/dist/extensions/index.cjs +2356 -0
- package/dist/extensions/index.d.ts +9 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +2435 -0
- package/dist/extensions/registry.d.ts +19 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/types.d.ts +10 -0
- package/dist/extensions/types.d.ts.map +1 -0
- package/dist/index.cjs +1519 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1460 -0
- package/dist/internal.cjs +156 -0
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +128 -0
- package/dist/jsonschema.cjs +18 -0
- package/dist/jsonschema.d.ts +2 -0
- package/dist/jsonschema.d.ts.map +1 -0
- package/dist/jsonschema.js +0 -0
- package/dist/stdlib/brand.d.ts +27 -0
- package/dist/stdlib/brand.d.ts.map +1 -0
- package/dist/stdlib/decimal.d.ts +324 -0
- package/dist/stdlib/decimal.d.ts.map +1 -0
- package/dist/stdlib/extension-method.d.ts +27 -0
- package/dist/stdlib/extension-method.d.ts.map +1 -0
- package/dist/stdlib/generated.d.ts +15 -0
- package/dist/stdlib/generated.d.ts.map +1 -0
- package/dist/stdlib/index.cjs +1519 -0
- package/dist/stdlib/index.d.ts +18 -0
- package/dist/stdlib/index.d.ts.map +1 -0
- package/dist/stdlib/index.js +1460 -0
- package/dist/stdlib/refs.d.ts +62 -0
- package/dist/stdlib/refs.d.ts.map +1 -0
- package/dist/stdlib/scalars.d.ts +141 -0
- package/dist/stdlib/scalars.d.ts.map +1 -0
- package/dist/stdlib/transform-strategies.d.ts +74 -0
- package/dist/stdlib/transform-strategies.d.ts.map +1 -0
- package/dist/stdlib/transforms.d.ts +97 -0
- package/dist/stdlib/transforms.d.ts.map +1 -0
- package/dist/stdlib/type-utils.d.ts +9 -0
- package/dist/stdlib/type-utils.d.ts.map +1 -0
- package/dist/stdlib/types.d.ts +281 -0
- package/dist/stdlib/types.d.ts.map +1 -0
- package/dist/stdlib/utils.d.ts +7 -0
- package/dist/stdlib/utils.d.ts.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +111 -0
- package/tslibs/5.9.3/lib.es2022.egress.d.ts +4328 -0
- package/tslibs/5.9.3/lib.es2022.restricted.d.ts +4067 -0
- package/tslibs/lib.egress.globals.d.ts +112 -0
- package/tslibs/lib.restricted.globals.d.ts +1 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (C) 2026 Stripe, Inc. (https://stripe.com)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/config-values/generate.ts
|
|
21
|
+
var generate_exports = {};
|
|
22
|
+
__export(generate_exports, {
|
|
23
|
+
STDLIB_IMPORT_PATH: () => STDLIB_IMPORT_PATH,
|
|
24
|
+
analyzeConfigType: () => analyzeConfigType,
|
|
25
|
+
analyzeConfigTypeInProject: () => analyzeConfigTypeInProject,
|
|
26
|
+
generateConfigDescriptor: () => generateConfigDescriptor
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(generate_exports);
|
|
29
|
+
|
|
30
|
+
// src/config-values/parse.ts
|
|
31
|
+
var import_ts_morph = require("ts-morph");
|
|
32
|
+
function analyzeConfigType(options) {
|
|
33
|
+
const project = new import_ts_morph.Project({
|
|
34
|
+
compilerOptions: { strict: true, skipLibCheck: true },
|
|
35
|
+
skipAddingFilesFromTsConfig: true
|
|
36
|
+
});
|
|
37
|
+
project.addSourceFileAtPath(options.filePath);
|
|
38
|
+
project.resolveSourceFileDependencies();
|
|
39
|
+
return analyzeConfigTypeInProject(project, options.filePath, options.typeName);
|
|
40
|
+
}
|
|
41
|
+
function analyzeConfigTypeInProject(project, filePath, typeName) {
|
|
42
|
+
const sourceFile = project.getSourceFileOrThrow(filePath);
|
|
43
|
+
const target = sourceFile.getInterface(typeName) ?? sourceFile.getTypeAlias(typeName) ?? sourceFile.getClass(typeName);
|
|
44
|
+
if (!target) {
|
|
45
|
+
throw new Error(`Type "${typeName}" not found in "${filePath}"`);
|
|
46
|
+
}
|
|
47
|
+
const state = { interfaces: [], enums: [] };
|
|
48
|
+
const type = target.getType();
|
|
49
|
+
const fields = walkObjectType(type, typeName, state);
|
|
50
|
+
state.interfaces.push({ name: typeName, fields });
|
|
51
|
+
return { rootTypeName: typeName, interfaces: state.interfaces, enums: state.enums };
|
|
52
|
+
}
|
|
53
|
+
function walkObjectType(type, context, state) {
|
|
54
|
+
const fields = [];
|
|
55
|
+
for (const sym of type.getProperties()) {
|
|
56
|
+
const decl = sym.getValueDeclaration();
|
|
57
|
+
if (!decl || !import_ts_morph.Node.isPropertySignature(decl) && !import_ts_morph.Node.isPropertyDeclaration(decl))
|
|
58
|
+
continue;
|
|
59
|
+
const hasQuestionMark = decl.hasQuestionToken();
|
|
60
|
+
const rawType = decl.getType();
|
|
61
|
+
const { classification, optional } = classifyType(
|
|
62
|
+
rawType,
|
|
63
|
+
`${context}.${sym.getName()}`,
|
|
64
|
+
state
|
|
65
|
+
);
|
|
66
|
+
fields.push({
|
|
67
|
+
name: sym.getName(),
|
|
68
|
+
classification,
|
|
69
|
+
optional: optional || hasQuestionMark
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return fields;
|
|
73
|
+
}
|
|
74
|
+
function classifyType(type, context, state) {
|
|
75
|
+
if (type.isUnion()) {
|
|
76
|
+
const members = type.getUnionTypes();
|
|
77
|
+
const hasNullable = members.some((m) => m.isUndefined() || m.isNull());
|
|
78
|
+
const nonNullable = members.filter((m) => !m.isUndefined() && !m.isNull());
|
|
79
|
+
if (nonNullable.length === 0) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`${context}: Type is only null/undefined, which is not a valid config type`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (nonNullable.every((m) => m.isBooleanLiteral())) {
|
|
85
|
+
return { classification: { kind: "primitive" }, optional: hasNullable };
|
|
86
|
+
}
|
|
87
|
+
if (nonNullable.every((m) => m.isStringLiteral())) {
|
|
88
|
+
const aliasSymbol = type.getAliasSymbol();
|
|
89
|
+
const typeName = aliasSymbol ? aliasSymbol.getName() : context.replace(/\./g, "_");
|
|
90
|
+
if (!state.enums.some((e) => e.name === typeName)) {
|
|
91
|
+
const values = nonNullable.map((m) => m.getLiteralValue());
|
|
92
|
+
state.enums.push({ name: typeName, values });
|
|
93
|
+
}
|
|
94
|
+
return { classification: { kind: "enum", typeName }, optional: hasNullable };
|
|
95
|
+
}
|
|
96
|
+
if (nonNullable.length === 1) {
|
|
97
|
+
const [sole] = nonNullable;
|
|
98
|
+
if (sole) {
|
|
99
|
+
const { classification } = classifyType(sole, context, state);
|
|
100
|
+
return { classification, optional: hasNullable };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
throw new Error(
|
|
104
|
+
`${context}: Union types are not supported in config types (only T | undefined or T | null is allowed)`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (type.isStringLiteral()) {
|
|
108
|
+
const value = type.getLiteralValue();
|
|
109
|
+
const typeName = context.replace(/\./g, "_");
|
|
110
|
+
if (!state.enums.some((e) => e.name === typeName)) {
|
|
111
|
+
state.enums.push({ name: typeName, values: [value] });
|
|
112
|
+
}
|
|
113
|
+
return { classification: { kind: "enum", typeName }, optional: false };
|
|
114
|
+
}
|
|
115
|
+
if (isStdlibDecimalType(type)) {
|
|
116
|
+
return { classification: { kind: "decimal" }, optional: false };
|
|
117
|
+
}
|
|
118
|
+
const dateSym = type.getSymbol();
|
|
119
|
+
if (dateSym?.getName() === "Date") {
|
|
120
|
+
const srcPath = dateSym.getDeclarations()[0]?.getSourceFile().getFilePath() ?? "";
|
|
121
|
+
const basename = srcPath.slice(srcPath.lastIndexOf("/") + 1);
|
|
122
|
+
if (basename.startsWith("lib.") && basename.endsWith(".d.ts")) {
|
|
123
|
+
return { classification: { kind: "datetime" }, optional: false };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (type.isString()) return { classification: { kind: "primitive" }, optional: false };
|
|
127
|
+
if (type.isNumber()) return { classification: { kind: "primitive" }, optional: false };
|
|
128
|
+
if (type.isBoolean()) return { classification: { kind: "primitive" }, optional: false };
|
|
129
|
+
if (type.isArray()) {
|
|
130
|
+
const elementType = type.getArrayElementTypeOrThrow();
|
|
131
|
+
const { classification: element } = classifyType(elementType, `${context}[]`, state);
|
|
132
|
+
return { classification: { kind: "array", element }, optional: false };
|
|
133
|
+
}
|
|
134
|
+
const stringIndexType = type.getStringIndexType();
|
|
135
|
+
if (stringIndexType) {
|
|
136
|
+
const { classification: value } = classifyType(
|
|
137
|
+
stringIndexType,
|
|
138
|
+
`${context}[string]`,
|
|
139
|
+
state
|
|
140
|
+
);
|
|
141
|
+
return { classification: { kind: "map", value }, optional: false };
|
|
142
|
+
}
|
|
143
|
+
if (type.isObject()) {
|
|
144
|
+
const typeSym = type.getSymbol();
|
|
145
|
+
const symName = typeSym?.getName();
|
|
146
|
+
const typeName = symName && !symName.startsWith("__") ? symName : context.replace(/\./g, "_");
|
|
147
|
+
if (!state.interfaces.some((i) => i.name === typeName)) {
|
|
148
|
+
const shapeFields = walkObjectType(type, typeName, state);
|
|
149
|
+
state.interfaces.push({ name: typeName, fields: shapeFields });
|
|
150
|
+
}
|
|
151
|
+
return { classification: { kind: "interface", typeName }, optional: false };
|
|
152
|
+
}
|
|
153
|
+
throw new Error(`${context}: Unsupported config field type: ${type.getText()}`);
|
|
154
|
+
}
|
|
155
|
+
function isStdlibDecimalType(type) {
|
|
156
|
+
return [type.getAliasSymbol(), type.getSymbol()].some((symbol) => {
|
|
157
|
+
if (symbol?.getName() !== "Decimal") return false;
|
|
158
|
+
return symbol.getDeclarations().some((declaration) => {
|
|
159
|
+
const srcPath = declaration.getSourceFile().getFilePath();
|
|
160
|
+
return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index");
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/config-values/generate.ts
|
|
166
|
+
var STDLIB_IMPORT_PATH = "@stripe/extensibility-sdk/stdlib";
|
|
167
|
+
function generateConfigDescriptor(result) {
|
|
168
|
+
const usedImports = /* @__PURE__ */ new Set();
|
|
169
|
+
const usedTypeImports = /* @__PURE__ */ new Set();
|
|
170
|
+
const lines = [];
|
|
171
|
+
if (result.enums.length > 0) usedImports.add("_ConfigEnum");
|
|
172
|
+
for (const enumDesc of result.enums) {
|
|
173
|
+
const values = enumDesc.values.map((v) => JSON.stringify(v)).join(", ");
|
|
174
|
+
lines.push(`const ${enumDesc.name}_ConfigValues = new _ConfigEnum([${values}]);`);
|
|
175
|
+
lines.push("");
|
|
176
|
+
}
|
|
177
|
+
usedImports.add("_ShapeDescriptor");
|
|
178
|
+
usedImports.add("_JsonWireToType");
|
|
179
|
+
for (const iface of result.interfaces) {
|
|
180
|
+
const constVarName = `${iface.name}_FromConfig`;
|
|
181
|
+
const entries = [];
|
|
182
|
+
for (const field of iface.fields) {
|
|
183
|
+
const inner = fieldTransformExpr(field.classification, usedImports);
|
|
184
|
+
const transform = wrapConfigTransform(inner, field.optional, usedImports);
|
|
185
|
+
entries.push(` { type: ${JSON.stringify(field.name)}, transform: ${transform} },`);
|
|
186
|
+
}
|
|
187
|
+
lines.push(
|
|
188
|
+
`const ${constVarName} = new _ShapeDescriptor<typeof _JsonWireToType, ${iface.name}>(${JSON.stringify(iface.name)}, [`
|
|
189
|
+
);
|
|
190
|
+
lines.push(...entries);
|
|
191
|
+
lines.push(`]);`);
|
|
192
|
+
lines.push("");
|
|
193
|
+
}
|
|
194
|
+
const rootTypeName = result.rootTypeName;
|
|
195
|
+
const rootConstVarName = `${rootTypeName}_FromConfig`;
|
|
196
|
+
usedImports.add("_applyConfig");
|
|
197
|
+
usedTypeImports.add("_ConfigApplicationContext");
|
|
198
|
+
lines.push(
|
|
199
|
+
`export function transform${rootTypeName}(raw: unknown, appCtx?: _ConfigApplicationContext): ${rootTypeName} {`
|
|
200
|
+
);
|
|
201
|
+
lines.push(` return _applyConfig(${rootConstVarName}, raw, appCtx);`);
|
|
202
|
+
lines.push(`}`);
|
|
203
|
+
return { lines, requiredImports: usedImports, requiredTypeImports: usedTypeImports };
|
|
204
|
+
}
|
|
205
|
+
function wrapConfigTransform(expr, isOptional, usedImports) {
|
|
206
|
+
if (isOptional) return expr;
|
|
207
|
+
if (expr === "_identity") {
|
|
208
|
+
usedImports.add("_required");
|
|
209
|
+
return "_required()";
|
|
210
|
+
}
|
|
211
|
+
usedImports.add("_required");
|
|
212
|
+
return `_required(${expr})`;
|
|
213
|
+
}
|
|
214
|
+
function fieldTransformExpr(classification, usedImports) {
|
|
215
|
+
switch (classification.kind) {
|
|
216
|
+
case "primitive": {
|
|
217
|
+
usedImports.add("_identity");
|
|
218
|
+
return "_identity";
|
|
219
|
+
}
|
|
220
|
+
case "decimal": {
|
|
221
|
+
usedImports.add("_translateDecimal");
|
|
222
|
+
return "_translateDecimal";
|
|
223
|
+
}
|
|
224
|
+
case "datetime": {
|
|
225
|
+
usedImports.add("_translateDateTime");
|
|
226
|
+
return "_translateDateTime";
|
|
227
|
+
}
|
|
228
|
+
case "enum": {
|
|
229
|
+
usedImports.add("_translateEnum");
|
|
230
|
+
return `_translateEnum(${classification.typeName}_ConfigValues)`;
|
|
231
|
+
}
|
|
232
|
+
case "array": {
|
|
233
|
+
usedImports.add("_translateArray");
|
|
234
|
+
const elemExpr = fieldTransformExpr(classification.element, usedImports);
|
|
235
|
+
return `_translateArray(${elemExpr})`;
|
|
236
|
+
}
|
|
237
|
+
case "map": {
|
|
238
|
+
usedImports.add("_translateMap");
|
|
239
|
+
usedImports.add("_identity");
|
|
240
|
+
const valueExpr = fieldTransformExpr(classification.value, usedImports);
|
|
241
|
+
return `_translateMap(_identity, ${valueExpr})`;
|
|
242
|
+
}
|
|
243
|
+
case "interface": {
|
|
244
|
+
usedImports.add("_translateShape");
|
|
245
|
+
const { typeName } = classification;
|
|
246
|
+
return `_translateShape(() => ${typeName}_FromConfig)`;
|
|
247
|
+
}
|
|
248
|
+
case "union":
|
|
249
|
+
throw new Error(`union types are not supported in config field descriptors`);
|
|
250
|
+
default: {
|
|
251
|
+
const _exhaustive = classification;
|
|
252
|
+
return _exhaustive;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
257
|
+
0 && (module.exports = {
|
|
258
|
+
STDLIB_IMPORT_PATH,
|
|
259
|
+
analyzeConfigType,
|
|
260
|
+
analyzeConfigTypeInProject,
|
|
261
|
+
generateConfigDescriptor
|
|
262
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits TypeScript code for a config field descriptor constant and its
|
|
3
|
+
* corresponding `transformX` function.
|
|
4
|
+
*
|
|
5
|
+
* @see ./parse.ts — produces the ConfigAnalysisResult input
|
|
6
|
+
*/
|
|
7
|
+
import type { ConfigAnalysisResult } from './parse.js';
|
|
8
|
+
export { analyzeConfigType, analyzeConfigTypeInProject, type ConfigAnalysisResult, type ConfigField, type ConfigInterfaceDescriptor, type ConfigEnumDescriptor, type FieldClassification, type ScalarFieldClassification, type StructuralFieldClassification, } from './parse.js';
|
|
9
|
+
/**
|
|
10
|
+
* The package specifier for the stdlib module used in generated import lines.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare const STDLIB_IMPORT_PATH = "@stripe/extensibility-sdk/stdlib";
|
|
15
|
+
/**
|
|
16
|
+
* Generated TypeScript source and imports for a config descriptor.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export interface GeneratedConfigDescriptor {
|
|
21
|
+
/** TypeScript code lines for the descriptor constant(s) and transform function */
|
|
22
|
+
lines: string[];
|
|
23
|
+
/** Value symbol names required from the stdlib module */
|
|
24
|
+
requiredImports: ReadonlySet<string>;
|
|
25
|
+
/** Type-only symbol names required from the stdlib module */
|
|
26
|
+
requiredTypeImports: ReadonlySet<string>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Generates TypeScript code for a config descriptor.
|
|
30
|
+
*
|
|
31
|
+
* Emits enum value constants first, then one `_ShapeDescriptor` constant per
|
|
32
|
+
* interface (in DFS post-order, so inner types appear before their references),
|
|
33
|
+
* followed by an exported `transformX(raw: unknown): X` function.
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export declare function generateConfigDescriptor(result: ConfigAnalysisResult): GeneratedConfigDescriptor;
|
|
38
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/config-values/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAuB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAG5E,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,kFAAkF;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yDAAyD;IACzD,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,6DAA6D;IAC7D,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,oBAAoB,GAC3B,yBAAyB,CA8C3B"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// src/config-values/parse.ts
|
|
2
|
+
import { Node, Project } from "ts-morph";
|
|
3
|
+
function analyzeConfigType(options) {
|
|
4
|
+
const project = new Project({
|
|
5
|
+
compilerOptions: { strict: true, skipLibCheck: true },
|
|
6
|
+
skipAddingFilesFromTsConfig: true
|
|
7
|
+
});
|
|
8
|
+
project.addSourceFileAtPath(options.filePath);
|
|
9
|
+
project.resolveSourceFileDependencies();
|
|
10
|
+
return analyzeConfigTypeInProject(project, options.filePath, options.typeName);
|
|
11
|
+
}
|
|
12
|
+
function analyzeConfigTypeInProject(project, filePath, typeName) {
|
|
13
|
+
const sourceFile = project.getSourceFileOrThrow(filePath);
|
|
14
|
+
const target = sourceFile.getInterface(typeName) ?? sourceFile.getTypeAlias(typeName) ?? sourceFile.getClass(typeName);
|
|
15
|
+
if (!target) {
|
|
16
|
+
throw new Error(`Type "${typeName}" not found in "${filePath}"`);
|
|
17
|
+
}
|
|
18
|
+
const state = { interfaces: [], enums: [] };
|
|
19
|
+
const type = target.getType();
|
|
20
|
+
const fields = walkObjectType(type, typeName, state);
|
|
21
|
+
state.interfaces.push({ name: typeName, fields });
|
|
22
|
+
return { rootTypeName: typeName, interfaces: state.interfaces, enums: state.enums };
|
|
23
|
+
}
|
|
24
|
+
function walkObjectType(type, context, state) {
|
|
25
|
+
const fields = [];
|
|
26
|
+
for (const sym of type.getProperties()) {
|
|
27
|
+
const decl = sym.getValueDeclaration();
|
|
28
|
+
if (!decl || !Node.isPropertySignature(decl) && !Node.isPropertyDeclaration(decl))
|
|
29
|
+
continue;
|
|
30
|
+
const hasQuestionMark = decl.hasQuestionToken();
|
|
31
|
+
const rawType = decl.getType();
|
|
32
|
+
const { classification, optional } = classifyType(
|
|
33
|
+
rawType,
|
|
34
|
+
`${context}.${sym.getName()}`,
|
|
35
|
+
state
|
|
36
|
+
);
|
|
37
|
+
fields.push({
|
|
38
|
+
name: sym.getName(),
|
|
39
|
+
classification,
|
|
40
|
+
optional: optional || hasQuestionMark
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return fields;
|
|
44
|
+
}
|
|
45
|
+
function classifyType(type, context, state) {
|
|
46
|
+
if (type.isUnion()) {
|
|
47
|
+
const members = type.getUnionTypes();
|
|
48
|
+
const hasNullable = members.some((m) => m.isUndefined() || m.isNull());
|
|
49
|
+
const nonNullable = members.filter((m) => !m.isUndefined() && !m.isNull());
|
|
50
|
+
if (nonNullable.length === 0) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`${context}: Type is only null/undefined, which is not a valid config type`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (nonNullable.every((m) => m.isBooleanLiteral())) {
|
|
56
|
+
return { classification: { kind: "primitive" }, optional: hasNullable };
|
|
57
|
+
}
|
|
58
|
+
if (nonNullable.every((m) => m.isStringLiteral())) {
|
|
59
|
+
const aliasSymbol = type.getAliasSymbol();
|
|
60
|
+
const typeName = aliasSymbol ? aliasSymbol.getName() : context.replace(/\./g, "_");
|
|
61
|
+
if (!state.enums.some((e) => e.name === typeName)) {
|
|
62
|
+
const values = nonNullable.map((m) => m.getLiteralValue());
|
|
63
|
+
state.enums.push({ name: typeName, values });
|
|
64
|
+
}
|
|
65
|
+
return { classification: { kind: "enum", typeName }, optional: hasNullable };
|
|
66
|
+
}
|
|
67
|
+
if (nonNullable.length === 1) {
|
|
68
|
+
const [sole] = nonNullable;
|
|
69
|
+
if (sole) {
|
|
70
|
+
const { classification } = classifyType(sole, context, state);
|
|
71
|
+
return { classification, optional: hasNullable };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
throw new Error(
|
|
75
|
+
`${context}: Union types are not supported in config types (only T | undefined or T | null is allowed)`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (type.isStringLiteral()) {
|
|
79
|
+
const value = type.getLiteralValue();
|
|
80
|
+
const typeName = context.replace(/\./g, "_");
|
|
81
|
+
if (!state.enums.some((e) => e.name === typeName)) {
|
|
82
|
+
state.enums.push({ name: typeName, values: [value] });
|
|
83
|
+
}
|
|
84
|
+
return { classification: { kind: "enum", typeName }, optional: false };
|
|
85
|
+
}
|
|
86
|
+
if (isStdlibDecimalType(type)) {
|
|
87
|
+
return { classification: { kind: "decimal" }, optional: false };
|
|
88
|
+
}
|
|
89
|
+
const dateSym = type.getSymbol();
|
|
90
|
+
if (dateSym?.getName() === "Date") {
|
|
91
|
+
const srcPath = dateSym.getDeclarations()[0]?.getSourceFile().getFilePath() ?? "";
|
|
92
|
+
const basename = srcPath.slice(srcPath.lastIndexOf("/") + 1);
|
|
93
|
+
if (basename.startsWith("lib.") && basename.endsWith(".d.ts")) {
|
|
94
|
+
return { classification: { kind: "datetime" }, optional: false };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (type.isString()) return { classification: { kind: "primitive" }, optional: false };
|
|
98
|
+
if (type.isNumber()) return { classification: { kind: "primitive" }, optional: false };
|
|
99
|
+
if (type.isBoolean()) return { classification: { kind: "primitive" }, optional: false };
|
|
100
|
+
if (type.isArray()) {
|
|
101
|
+
const elementType = type.getArrayElementTypeOrThrow();
|
|
102
|
+
const { classification: element } = classifyType(elementType, `${context}[]`, state);
|
|
103
|
+
return { classification: { kind: "array", element }, optional: false };
|
|
104
|
+
}
|
|
105
|
+
const stringIndexType = type.getStringIndexType();
|
|
106
|
+
if (stringIndexType) {
|
|
107
|
+
const { classification: value } = classifyType(
|
|
108
|
+
stringIndexType,
|
|
109
|
+
`${context}[string]`,
|
|
110
|
+
state
|
|
111
|
+
);
|
|
112
|
+
return { classification: { kind: "map", value }, optional: false };
|
|
113
|
+
}
|
|
114
|
+
if (type.isObject()) {
|
|
115
|
+
const typeSym = type.getSymbol();
|
|
116
|
+
const symName = typeSym?.getName();
|
|
117
|
+
const typeName = symName && !symName.startsWith("__") ? symName : context.replace(/\./g, "_");
|
|
118
|
+
if (!state.interfaces.some((i) => i.name === typeName)) {
|
|
119
|
+
const shapeFields = walkObjectType(type, typeName, state);
|
|
120
|
+
state.interfaces.push({ name: typeName, fields: shapeFields });
|
|
121
|
+
}
|
|
122
|
+
return { classification: { kind: "interface", typeName }, optional: false };
|
|
123
|
+
}
|
|
124
|
+
throw new Error(`${context}: Unsupported config field type: ${type.getText()}`);
|
|
125
|
+
}
|
|
126
|
+
function isStdlibDecimalType(type) {
|
|
127
|
+
return [type.getAliasSymbol(), type.getSymbol()].some((symbol) => {
|
|
128
|
+
if (symbol?.getName() !== "Decimal") return false;
|
|
129
|
+
return symbol.getDeclarations().some((declaration) => {
|
|
130
|
+
const srcPath = declaration.getSourceFile().getFilePath();
|
|
131
|
+
return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/config-values/generate.ts
|
|
137
|
+
var STDLIB_IMPORT_PATH = "@stripe/extensibility-sdk/stdlib";
|
|
138
|
+
function generateConfigDescriptor(result) {
|
|
139
|
+
const usedImports = /* @__PURE__ */ new Set();
|
|
140
|
+
const usedTypeImports = /* @__PURE__ */ new Set();
|
|
141
|
+
const lines = [];
|
|
142
|
+
if (result.enums.length > 0) usedImports.add("_ConfigEnum");
|
|
143
|
+
for (const enumDesc of result.enums) {
|
|
144
|
+
const values = enumDesc.values.map((v) => JSON.stringify(v)).join(", ");
|
|
145
|
+
lines.push(`const ${enumDesc.name}_ConfigValues = new _ConfigEnum([${values}]);`);
|
|
146
|
+
lines.push("");
|
|
147
|
+
}
|
|
148
|
+
usedImports.add("_ShapeDescriptor");
|
|
149
|
+
usedImports.add("_JsonWireToType");
|
|
150
|
+
for (const iface of result.interfaces) {
|
|
151
|
+
const constVarName = `${iface.name}_FromConfig`;
|
|
152
|
+
const entries = [];
|
|
153
|
+
for (const field of iface.fields) {
|
|
154
|
+
const inner = fieldTransformExpr(field.classification, usedImports);
|
|
155
|
+
const transform = wrapConfigTransform(inner, field.optional, usedImports);
|
|
156
|
+
entries.push(` { type: ${JSON.stringify(field.name)}, transform: ${transform} },`);
|
|
157
|
+
}
|
|
158
|
+
lines.push(
|
|
159
|
+
`const ${constVarName} = new _ShapeDescriptor<typeof _JsonWireToType, ${iface.name}>(${JSON.stringify(iface.name)}, [`
|
|
160
|
+
);
|
|
161
|
+
lines.push(...entries);
|
|
162
|
+
lines.push(`]);`);
|
|
163
|
+
lines.push("");
|
|
164
|
+
}
|
|
165
|
+
const rootTypeName = result.rootTypeName;
|
|
166
|
+
const rootConstVarName = `${rootTypeName}_FromConfig`;
|
|
167
|
+
usedImports.add("_applyConfig");
|
|
168
|
+
usedTypeImports.add("_ConfigApplicationContext");
|
|
169
|
+
lines.push(
|
|
170
|
+
`export function transform${rootTypeName}(raw: unknown, appCtx?: _ConfigApplicationContext): ${rootTypeName} {`
|
|
171
|
+
);
|
|
172
|
+
lines.push(` return _applyConfig(${rootConstVarName}, raw, appCtx);`);
|
|
173
|
+
lines.push(`}`);
|
|
174
|
+
return { lines, requiredImports: usedImports, requiredTypeImports: usedTypeImports };
|
|
175
|
+
}
|
|
176
|
+
function wrapConfigTransform(expr, isOptional, usedImports) {
|
|
177
|
+
if (isOptional) return expr;
|
|
178
|
+
if (expr === "_identity") {
|
|
179
|
+
usedImports.add("_required");
|
|
180
|
+
return "_required()";
|
|
181
|
+
}
|
|
182
|
+
usedImports.add("_required");
|
|
183
|
+
return `_required(${expr})`;
|
|
184
|
+
}
|
|
185
|
+
function fieldTransformExpr(classification, usedImports) {
|
|
186
|
+
switch (classification.kind) {
|
|
187
|
+
case "primitive": {
|
|
188
|
+
usedImports.add("_identity");
|
|
189
|
+
return "_identity";
|
|
190
|
+
}
|
|
191
|
+
case "decimal": {
|
|
192
|
+
usedImports.add("_translateDecimal");
|
|
193
|
+
return "_translateDecimal";
|
|
194
|
+
}
|
|
195
|
+
case "datetime": {
|
|
196
|
+
usedImports.add("_translateDateTime");
|
|
197
|
+
return "_translateDateTime";
|
|
198
|
+
}
|
|
199
|
+
case "enum": {
|
|
200
|
+
usedImports.add("_translateEnum");
|
|
201
|
+
return `_translateEnum(${classification.typeName}_ConfigValues)`;
|
|
202
|
+
}
|
|
203
|
+
case "array": {
|
|
204
|
+
usedImports.add("_translateArray");
|
|
205
|
+
const elemExpr = fieldTransformExpr(classification.element, usedImports);
|
|
206
|
+
return `_translateArray(${elemExpr})`;
|
|
207
|
+
}
|
|
208
|
+
case "map": {
|
|
209
|
+
usedImports.add("_translateMap");
|
|
210
|
+
usedImports.add("_identity");
|
|
211
|
+
const valueExpr = fieldTransformExpr(classification.value, usedImports);
|
|
212
|
+
return `_translateMap(_identity, ${valueExpr})`;
|
|
213
|
+
}
|
|
214
|
+
case "interface": {
|
|
215
|
+
usedImports.add("_translateShape");
|
|
216
|
+
const { typeName } = classification;
|
|
217
|
+
return `_translateShape(() => ${typeName}_FromConfig)`;
|
|
218
|
+
}
|
|
219
|
+
case "union":
|
|
220
|
+
throw new Error(`union types are not supported in config field descriptors`);
|
|
221
|
+
default: {
|
|
222
|
+
const _exhaustive = classification;
|
|
223
|
+
return _exhaustive;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
export {
|
|
228
|
+
STDLIB_IMPORT_PATH,
|
|
229
|
+
analyzeConfigType,
|
|
230
|
+
analyzeConfigTypeInProject,
|
|
231
|
+
generateConfigDescriptor
|
|
232
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyzes a config type using ts-morph and produces a field classification
|
|
3
|
+
* descriptor for runtime transformer generation.
|
|
4
|
+
*
|
|
5
|
+
* @see ./generate.ts — converts the descriptor to TypeScript code
|
|
6
|
+
*/
|
|
7
|
+
import type { Project as MorphProject } from 'ts-morph';
|
|
8
|
+
/** @internal */
|
|
9
|
+
export type ScalarFieldClassification = {
|
|
10
|
+
kind: 'primitive';
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'decimal';
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'datetime';
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'enum';
|
|
17
|
+
typeName: string;
|
|
18
|
+
};
|
|
19
|
+
/** @internal */
|
|
20
|
+
export type StructuralFieldClassification = {
|
|
21
|
+
kind: 'interface';
|
|
22
|
+
typeName: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'union';
|
|
25
|
+
typeName: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'array';
|
|
28
|
+
element: FieldClassification;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'map';
|
|
31
|
+
value: FieldClassification;
|
|
32
|
+
};
|
|
33
|
+
/** @internal */
|
|
34
|
+
export type FieldClassification = ScalarFieldClassification | StructuralFieldClassification;
|
|
35
|
+
/** @internal */
|
|
36
|
+
export interface ConfigField {
|
|
37
|
+
name: string;
|
|
38
|
+
classification: FieldClassification;
|
|
39
|
+
optional: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** @internal */
|
|
42
|
+
export interface ConfigInterfaceDescriptor {
|
|
43
|
+
name: string;
|
|
44
|
+
fields: ConfigField[];
|
|
45
|
+
}
|
|
46
|
+
/** @internal */
|
|
47
|
+
export interface ConfigEnumDescriptor {
|
|
48
|
+
name: string;
|
|
49
|
+
values: readonly string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The result of analyzing a config type.
|
|
53
|
+
*
|
|
54
|
+
* `interfaces` is in DFS post-order: inner types appear before the types that
|
|
55
|
+
* reference them, so the root type is always last.
|
|
56
|
+
* `enums` is in discovery order, deduplicated by name.
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export interface ConfigAnalysisResult {
|
|
60
|
+
rootTypeName: string;
|
|
61
|
+
interfaces: ConfigInterfaceDescriptor[];
|
|
62
|
+
enums: ConfigEnumDescriptor[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Analyzes a named config type in a source file, producing a descriptor
|
|
66
|
+
* for runtime transformation.
|
|
67
|
+
*
|
|
68
|
+
* Creates a ts-morph Project from the file system. For testing with
|
|
69
|
+
* in-memory files, use `analyzeConfigTypeInProject` directly.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
export declare function analyzeConfigType(options: {
|
|
73
|
+
filePath: string;
|
|
74
|
+
typeName: string;
|
|
75
|
+
}): ConfigAnalysisResult;
|
|
76
|
+
/**
|
|
77
|
+
* Analyzes a named config type using a caller-supplied ts-morph Project.
|
|
78
|
+
* Use this in tests to pass an in-memory project.
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
export declare function analyzeConfigTypeInProject(project: MorphProject, filePath: string, typeName: string): ConfigAnalysisResult;
|
|
82
|
+
/** @internal */
|
|
83
|
+
export interface AccumulatorState {
|
|
84
|
+
interfaces: ConfigInterfaceDescriptor[];
|
|
85
|
+
enums: ConfigEnumDescriptor[];
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/config-values/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAQ,OAAO,IAAI,YAAY,EAAE,MAAM,UAAU,CAAC;AAM9D,gBAAgB;AAChB,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,gBAAgB;AAChB,MAAM,MAAM,6BAA6B,GACrC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAEhD,gBAAgB;AAChB,MAAM,MAAM,mBAAmB,GAC3B,yBAAyB,GACzB,6BAA6B,CAAC;AAMlC,gBAAgB;AAChB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,mBAAmB,CAAC;IACpC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,gBAAgB;AAChB,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,gBAAgB;AAChB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC/B;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,oBAAoB,CAQvB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,oBAAoB,CAiBtB;AAMD,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,yBAAyB,EAAE,CAAC;IACxC,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC/B"}
|