@tappify/extension-sdk 2.0.0
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 +21 -0
- package/dist/chunk-2DBSVKAU.cjs +65 -0
- package/dist/chunk-2DBSVKAU.cjs.map +1 -0
- package/dist/chunk-3YWVYA42.cjs +142 -0
- package/dist/chunk-3YWVYA42.cjs.map +1 -0
- package/dist/chunk-4C5Z3CIK.mjs +26 -0
- package/dist/chunk-4C5Z3CIK.mjs.map +1 -0
- package/dist/chunk-5AAPD5WV.cjs +250 -0
- package/dist/chunk-5AAPD5WV.cjs.map +1 -0
- package/dist/chunk-7KIKOH5H.cjs +26 -0
- package/dist/chunk-7KIKOH5H.cjs.map +1 -0
- package/dist/chunk-BDCX6LRQ.mjs +250 -0
- package/dist/chunk-BDCX6LRQ.mjs.map +1 -0
- package/dist/chunk-CSTYBKZC.mjs +65 -0
- package/dist/chunk-CSTYBKZC.mjs.map +1 -0
- package/dist/chunk-IGK2AP6J.mjs +142 -0
- package/dist/chunk-IGK2AP6J.mjs.map +1 -0
- package/dist/chunk-MNDVYPEP.mjs +302 -0
- package/dist/chunk-MNDVYPEP.mjs.map +1 -0
- package/dist/chunk-OPPYEA7F.cjs +33 -0
- package/dist/chunk-OPPYEA7F.cjs.map +1 -0
- package/dist/chunk-PYJMJF44.cjs +302 -0
- package/dist/chunk-PYJMJF44.cjs.map +1 -0
- package/dist/chunk-QHM7XNRK.mjs +33 -0
- package/dist/chunk-QHM7XNRK.mjs.map +1 -0
- package/dist/chunk-RMUWRESK.cjs +365 -0
- package/dist/chunk-RMUWRESK.cjs.map +1 -0
- package/dist/chunk-ZT35X7KL.mjs +365 -0
- package/dist/chunk-ZT35X7KL.mjs.map +1 -0
- package/dist/codegen.cjs +300 -0
- package/dist/codegen.cjs.map +1 -0
- package/dist/codegen.d.cts +432 -0
- package/dist/codegen.d.ts +432 -0
- package/dist/codegen.mjs +272 -0
- package/dist/codegen.mjs.map +1 -0
- package/dist/constants-DJ_KgZpN.d.cts +449 -0
- package/dist/constants-DJ_KgZpN.d.ts +449 -0
- package/dist/context-Dt6xh_5t.d.cts +30 -0
- package/dist/context-Ml7k_V14.d.ts +30 -0
- package/dist/errors-COsBh7kd.d.cts +88 -0
- package/dist/errors-COsBh7kd.d.ts +88 -0
- package/dist/handler-CZIlZ5vu.d.ts +227 -0
- package/dist/handler-kU9Jf36K.d.cts +227 -0
- package/dist/host.cjs +24 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.cts +24 -0
- package/dist/host.d.ts +24 -0
- package/dist/host.mjs +24 -0
- package/dist/host.mjs.map +1 -0
- package/dist/index.cjs +698 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1016 -0
- package/dist/index.d.ts +1016 -0
- package/dist/index.mjs +698 -0
- package/dist/index.mjs.map +1 -0
- package/dist/manifest.cjs +872 -0
- package/dist/manifest.cjs.map +1 -0
- package/dist/manifest.d.cts +432 -0
- package/dist/manifest.d.ts +432 -0
- package/dist/manifest.mjs +872 -0
- package/dist/manifest.mjs.map +1 -0
- package/dist/matchers-Cz93AK1n.d.cts +74 -0
- package/dist/matchers-Cz93AK1n.d.ts +74 -0
- package/dist/server.cjs +210 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +243 -0
- package/dist/server.d.ts +243 -0
- package/dist/server.mjs +210 -0
- package/dist/server.mjs.map +1 -0
- package/dist/styles.css +367 -0
- package/dist/testing/index.cjs +887 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +512 -0
- package/dist/testing/index.d.ts +512 -0
- package/dist/testing/index.mjs +887 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/testing/jest.cjs +17 -0
- package/dist/testing/jest.cjs.map +1 -0
- package/dist/testing/jest.d.cts +12 -0
- package/dist/testing/jest.d.ts +12 -0
- package/dist/testing/jest.mjs +17 -0
- package/dist/testing/jest.mjs.map +1 -0
- package/dist/testing/vitest.cjs +15 -0
- package/dist/testing/vitest.cjs.map +1 -0
- package/dist/testing/vitest.d.cts +10 -0
- package/dist/testing/vitest.d.ts +10 -0
- package/dist/testing/vitest.mjs +15 -0
- package/dist/testing/vitest.mjs.map +1 -0
- package/dist/types-DDAGLpov.d.ts +715 -0
- package/dist/types-DrpQSv_2.d.cts +715 -0
- package/dist/vite.cjs +1344 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +434 -0
- package/dist/vite.d.ts +434 -0
- package/dist/vite.mjs +1314 -0
- package/dist/vite.mjs.map +1 -0
- package/package.json +268 -0
- package/schema/extension-v2.json +1500 -0
package/dist/codegen.cjs
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
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/codegen.ts
|
|
21
|
+
var codegen_exports = {};
|
|
22
|
+
__export(codegen_exports, {
|
|
23
|
+
GENERATED_HEADER: () => GENERATED_HEADER,
|
|
24
|
+
generateTypes: () => generateTypes
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(codegen_exports);
|
|
27
|
+
|
|
28
|
+
// src/codegen/generate.ts
|
|
29
|
+
var import_json_schema_to_typescript = require("json-schema-to-typescript");
|
|
30
|
+
var import_node_path = require("path");
|
|
31
|
+
|
|
32
|
+
// src/client/errors.ts
|
|
33
|
+
var TAP_ERROR_CODES = [
|
|
34
|
+
"TAP_OUTSIDE_HOST",
|
|
35
|
+
"TAP_SCOPE_MISSING",
|
|
36
|
+
"TAP_UNKNOWN_COLLECTION",
|
|
37
|
+
"TAP_UNKNOWN_PROCEDURE",
|
|
38
|
+
"TAP_NO_PORTAL",
|
|
39
|
+
"TAP_NO_QUERY_CLIENT",
|
|
40
|
+
"TAP_MANIFEST_INVALID",
|
|
41
|
+
"TAP_ENTRY_MISSING",
|
|
42
|
+
"TAP_STYLES_UNRESOLVED",
|
|
43
|
+
"TAP_SCHEMA_UNRESOLVED",
|
|
44
|
+
"TAP_TOKEN_MISSING",
|
|
45
|
+
"TAP_TOKEN_INVALID",
|
|
46
|
+
"TAP_TOKEN_AUDIENCE",
|
|
47
|
+
"TAP_EVENT_ID_MISSING",
|
|
48
|
+
"TAP_BODY_INVALID",
|
|
49
|
+
"TAP_BODY_TOO_LARGE",
|
|
50
|
+
"TAP_ROUTE_UNKNOWN",
|
|
51
|
+
"TAP_HANDLER_MISSING",
|
|
52
|
+
"TAP_INTERNAL_ERROR",
|
|
53
|
+
"TAP_WEBHOOK_REJECTED",
|
|
54
|
+
"TAP_TEST_TARGET_INVALID"
|
|
55
|
+
];
|
|
56
|
+
var CODE_SET = new Set(TAP_ERROR_CODES);
|
|
57
|
+
var TapError = class extends Error {
|
|
58
|
+
constructor(code, message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = "TapError";
|
|
61
|
+
this.code = code;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Narrows an unknown value to a `TapError`, by name and by a code it
|
|
65
|
+
* recognises, so it holds across module instances.
|
|
66
|
+
*/
|
|
67
|
+
static is(value) {
|
|
68
|
+
return value instanceof Error && value.name === "TapError" && "code" in value && typeof value.code === "string" && CODE_SET.has(value.code);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/codegen/generate.ts
|
|
73
|
+
var GENERATED_HEADER = `/* eslint-disable */
|
|
74
|
+
/**
|
|
75
|
+
* Generated by \`tappify extension types\`. Do not edit by hand.
|
|
76
|
+
* Re-run the command after changing tappify.extension.json or any schema it points at.
|
|
77
|
+
*/`;
|
|
78
|
+
var STYLE = {
|
|
79
|
+
bracketSpacing: true,
|
|
80
|
+
printWidth: 80,
|
|
81
|
+
semi: true,
|
|
82
|
+
singleQuote: true,
|
|
83
|
+
tabWidth: 2,
|
|
84
|
+
trailingComma: "all",
|
|
85
|
+
useTabs: false
|
|
86
|
+
};
|
|
87
|
+
function pascal(value) {
|
|
88
|
+
return value.split(/[^A-Za-z0-9]+/).filter((part) => part !== "").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
89
|
+
}
|
|
90
|
+
function createEmitter(resolveSchema) {
|
|
91
|
+
const used = /* @__PURE__ */ new Set();
|
|
92
|
+
const blocks = [];
|
|
93
|
+
return {
|
|
94
|
+
async declare(preferredName, schema) {
|
|
95
|
+
let name = pascal(preferredName);
|
|
96
|
+
let suffix = 2;
|
|
97
|
+
while (used.has(name)) {
|
|
98
|
+
name = `${pascal(preferredName)}${String(suffix)}`;
|
|
99
|
+
suffix += 1;
|
|
100
|
+
}
|
|
101
|
+
used.add(name);
|
|
102
|
+
const resolved = resolveSchema(schema);
|
|
103
|
+
const input = {
|
|
104
|
+
...resolved.schema,
|
|
105
|
+
title: name
|
|
106
|
+
};
|
|
107
|
+
const text = await (0, import_json_schema_to_typescript.compile)(input, name, {
|
|
108
|
+
bannerComment: "",
|
|
109
|
+
additionalProperties: false,
|
|
110
|
+
declareExternallyReferenced: true,
|
|
111
|
+
enableConstEnums: false,
|
|
112
|
+
format: true,
|
|
113
|
+
style: STYLE,
|
|
114
|
+
unknownAny: true,
|
|
115
|
+
...resolved.cwd === void 0 ? {} : { cwd: resolved.cwd }
|
|
116
|
+
});
|
|
117
|
+
blocks.push(text.trim());
|
|
118
|
+
return name;
|
|
119
|
+
},
|
|
120
|
+
declarations() {
|
|
121
|
+
return blocks;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function credentialSchema(fields) {
|
|
126
|
+
const properties = {};
|
|
127
|
+
const required = [];
|
|
128
|
+
for (const field of fields) {
|
|
129
|
+
const property = field.type === "select" && field.options ? { type: "string", enum: field.options } : { type: "string" };
|
|
130
|
+
if (field.help !== void 0) property.description = field.help;
|
|
131
|
+
properties[field.name] = property;
|
|
132
|
+
if (field.required) required.push(field.name);
|
|
133
|
+
}
|
|
134
|
+
return { type: "object", properties, required, additionalProperties: false };
|
|
135
|
+
}
|
|
136
|
+
async function generateTypes(options) {
|
|
137
|
+
const { manifest, registrySnapshot } = options;
|
|
138
|
+
const contributes = manifest.contributes;
|
|
139
|
+
const resolveSchema = (schema) => {
|
|
140
|
+
const ref = schema.$ref;
|
|
141
|
+
if (typeof ref !== "string" || ref.startsWith("#")) {
|
|
142
|
+
return { schema, cwd: options.cwd };
|
|
143
|
+
}
|
|
144
|
+
if (options.readSchemaFile === void 0) {
|
|
145
|
+
throw new TapError(
|
|
146
|
+
"TAP_SCHEMA_UNRESOLVED",
|
|
147
|
+
`The manifest points at the schema file "${ref}", but this call passed no readSchemaFile. Run \`tappify extension types\`, which reads schema files from the extension directory, or supply readSchemaFile.`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
schema: options.readSchemaFile(ref),
|
|
152
|
+
cwd: options.cwd === void 0 ? void 0 : (0, import_node_path.dirname)((0, import_node_path.join)(options.cwd, ref))
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
const emitter = createEmitter(resolveSchema);
|
|
156
|
+
const augmentations = [];
|
|
157
|
+
const storageEntries = Object.entries(contributes.storage ?? {});
|
|
158
|
+
if (storageEntries.length > 0) {
|
|
159
|
+
const lines = [];
|
|
160
|
+
for (const [name, collection] of storageEntries) {
|
|
161
|
+
const typeName = await emitter.declare(name, collection.schema);
|
|
162
|
+
const kind = collection.singleton === true ? "singleton" : "collection";
|
|
163
|
+
lines.push(
|
|
164
|
+
` '${name}': { kind: '${kind}'; scope: '${collection.scope}'; document: ${typeName} };`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
augmentations.push(` interface TapStorageMap {
|
|
168
|
+
${lines.join("\n")}
|
|
169
|
+
}`);
|
|
170
|
+
}
|
|
171
|
+
const procedureEntries = Object.entries(manifest.server?.procedures ?? {});
|
|
172
|
+
if (procedureEntries.length > 0) {
|
|
173
|
+
const lines = [];
|
|
174
|
+
for (const [name, declaration] of procedureEntries) {
|
|
175
|
+
const inputName = await emitter.declare(
|
|
176
|
+
`${name}Input`,
|
|
177
|
+
declaration.input
|
|
178
|
+
);
|
|
179
|
+
const outputName = await emitter.declare(
|
|
180
|
+
`${name}Output`,
|
|
181
|
+
declaration.output
|
|
182
|
+
);
|
|
183
|
+
lines.push(
|
|
184
|
+
` '${name}': { input: ${inputName}; output: ${outputName} };`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
augmentations.push(
|
|
188
|
+
` interface TapProcedureMap {
|
|
189
|
+
${lines.join("\n")}
|
|
190
|
+
}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const actions = contributes.ai?.actions ?? [];
|
|
194
|
+
if (actions.length > 0) {
|
|
195
|
+
const lines = [];
|
|
196
|
+
for (const action of actions) {
|
|
197
|
+
const name = await emitter.declare(`${action.id}Input`, action.input);
|
|
198
|
+
lines.push(` '${action.id}': { input: ${name} };`);
|
|
199
|
+
}
|
|
200
|
+
augmentations.push(` interface TapActionMap {
|
|
201
|
+
${lines.join("\n")}
|
|
202
|
+
}`);
|
|
203
|
+
}
|
|
204
|
+
const tools = contributes.ai?.tools ?? [];
|
|
205
|
+
if (tools.length > 0) {
|
|
206
|
+
const lines = [];
|
|
207
|
+
for (const tool of tools) {
|
|
208
|
+
const name = await emitter.declare(`${tool.id}Input`, tool.input);
|
|
209
|
+
lines.push(` '${tool.id}': { input: ${name} };`);
|
|
210
|
+
}
|
|
211
|
+
augmentations.push(` interface TapToolMap {
|
|
212
|
+
${lines.join("\n")}
|
|
213
|
+
}`);
|
|
214
|
+
}
|
|
215
|
+
const prompts = (contributes.ai?.prompts ?? []).filter(
|
|
216
|
+
(prompt) => prompt.input !== void 0
|
|
217
|
+
);
|
|
218
|
+
if (prompts.length > 0) {
|
|
219
|
+
const lines = [];
|
|
220
|
+
for (const prompt of prompts) {
|
|
221
|
+
const name = await emitter.declare(
|
|
222
|
+
`${prompt.id}PromptInput`,
|
|
223
|
+
prompt.input ?? { type: "object" }
|
|
224
|
+
);
|
|
225
|
+
lines.push(` '${prompt.id}': { input: ${name} };`);
|
|
226
|
+
}
|
|
227
|
+
augmentations.push(` interface TapPromptMap {
|
|
228
|
+
${lines.join("\n")}
|
|
229
|
+
}`);
|
|
230
|
+
}
|
|
231
|
+
const webhooks = contributes.webhooks ?? [];
|
|
232
|
+
if (webhooks.length > 0) {
|
|
233
|
+
const lines = [];
|
|
234
|
+
for (const webhook of webhooks) {
|
|
235
|
+
const name = await emitter.declare(
|
|
236
|
+
`${webhook.event}Payload`,
|
|
237
|
+
webhook.payload
|
|
238
|
+
);
|
|
239
|
+
lines.push(` '${webhook.event}': ${name};`);
|
|
240
|
+
}
|
|
241
|
+
augmentations.push(` interface TapWebhookMap {
|
|
242
|
+
${lines.join("\n")}
|
|
243
|
+
}`);
|
|
244
|
+
}
|
|
245
|
+
if (registrySnapshot !== void 0 && registrySnapshot.events.length > 0) {
|
|
246
|
+
const lines = [];
|
|
247
|
+
for (const event of registrySnapshot.events) {
|
|
248
|
+
const name = await emitter.declare(
|
|
249
|
+
`${event.name}Event`,
|
|
250
|
+
event.payload ?? { type: "object" }
|
|
251
|
+
);
|
|
252
|
+
lines.push(` '${event.name}': ${name};`);
|
|
253
|
+
}
|
|
254
|
+
augmentations.push(
|
|
255
|
+
` interface TapHostEventMap {
|
|
256
|
+
${lines.join("\n")}
|
|
257
|
+
}`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
const telemetry = manifest.telemetry ?? [];
|
|
261
|
+
if (telemetry.length > 0) {
|
|
262
|
+
const lines = telemetry.map((name) => ` '${name}': true;`);
|
|
263
|
+
augmentations.push(
|
|
264
|
+
` interface TapTelemetryEvents {
|
|
265
|
+
${lines.join("\n")}
|
|
266
|
+
}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
if (contributes.settings) {
|
|
270
|
+
const name = await emitter.declare("Settings", contributes.settings.schema);
|
|
271
|
+
augmentations.push(` interface TapSettings extends ${name} {}`);
|
|
272
|
+
}
|
|
273
|
+
const credentialFields = contributes.connector?.auth?.fields ?? [];
|
|
274
|
+
if (credentialFields.length > 0) {
|
|
275
|
+
const name = await emitter.declare(
|
|
276
|
+
"Credentials",
|
|
277
|
+
credentialSchema(credentialFields)
|
|
278
|
+
);
|
|
279
|
+
augmentations.push(` interface TapCredentials extends ${name} {}`);
|
|
280
|
+
}
|
|
281
|
+
const declarations = emitter.declarations();
|
|
282
|
+
const module2 = augmentations.length === 0 ? "declare module '@tappify/extension-sdk' {}" : `declare module '@tappify/extension-sdk' {
|
|
283
|
+
${augmentations.join("\n\n")}
|
|
284
|
+
}`;
|
|
285
|
+
return [
|
|
286
|
+
GENERATED_HEADER,
|
|
287
|
+
"",
|
|
288
|
+
...declarations.length > 0 ? [declarations.join("\n\n"), ""] : [],
|
|
289
|
+
module2,
|
|
290
|
+
"",
|
|
291
|
+
"export {};",
|
|
292
|
+
""
|
|
293
|
+
].join("\n");
|
|
294
|
+
}
|
|
295
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
296
|
+
0 && (module.exports = {
|
|
297
|
+
GENERATED_HEADER,
|
|
298
|
+
generateTypes
|
|
299
|
+
});
|
|
300
|
+
//# sourceMappingURL=codegen.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/codegen.ts","../src/codegen/generate.ts","../src/client/errors.ts"],"sourcesContent":["export { GENERATED_HEADER, generateTypes } from './codegen/generate';\nexport type {\n GenerateTypesOptions,\n RegistrySnapshot,\n} from './codegen/generate';\n","import { compile } from 'json-schema-to-typescript';\nimport { dirname, join } from 'node:path';\nimport { TapError } from '../client/errors';\nimport type {\n CredentialField,\n ExtensionManifest,\n JsonSchema,\n} from '../manifest/types';\n\nexport const GENERATED_HEADER = `/* eslint-disable */\n/**\n * Generated by \\`tappify extension types\\`. Do not edit by hand.\n * Re-run the command after changing tappify.extension.json or any schema it points at.\n */`;\n\nexport interface RegistrySnapshot {\n events: { name: string; payload?: JsonSchema }[];\n}\n\nexport interface GenerateTypesOptions {\n manifest: ExtensionManifest;\n registrySnapshot?: RegistrySnapshot;\n readSchemaFile?(path: string): JsonSchema;\n /**\n * The extension root. A `$ref` inside a schema file resolves against that\n * file's own directory under it, the way the host and the Tap Store read\n * it; without a root the process directory stands in.\n */\n cwd?: string;\n}\n\nconst STYLE = {\n bracketSpacing: true,\n printWidth: 80,\n semi: true,\n singleQuote: true,\n tabWidth: 2,\n trailingComma: 'all',\n useTabs: false,\n} as const;\n\nfunction pascal(value: string): string {\n return value\n .split(/[^A-Za-z0-9]+/)\n .filter(part => part !== '')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\ninterface Emitter {\n declare(preferredName: string, schema: JsonSchema): Promise<string>;\n declarations(): string[];\n}\n\ninterface ResolvedSchema {\n schema: JsonSchema;\n /** Where the schema's own nested `$ref`s resolve from. */\n cwd?: string;\n}\n\nfunction createEmitter(\n resolveSchema: (schema: JsonSchema) => ResolvedSchema,\n): Emitter {\n const used = new Set<string>();\n const blocks: string[] = [];\n\n return {\n async declare(preferredName, schema) {\n let name = pascal(preferredName);\n let suffix = 2;\n while (used.has(name)) {\n name = `${pascal(preferredName)}${String(suffix)}`;\n suffix += 1;\n }\n used.add(name);\n\n const resolved = resolveSchema(schema);\n const input: Parameters<typeof compile>[0] = {\n ...resolved.schema,\n title: name,\n };\n\n const text = await compile(input, name, {\n bannerComment: '',\n additionalProperties: false,\n declareExternallyReferenced: true,\n enableConstEnums: false,\n format: true,\n style: STYLE,\n unknownAny: true,\n ...(resolved.cwd === undefined ? {} : { cwd: resolved.cwd }),\n });\n\n blocks.push(text.trim());\n return name;\n },\n declarations() {\n return blocks;\n },\n };\n}\n\nfunction credentialSchema(fields: CredentialField[]): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const field of fields) {\n const property: JsonSchema =\n field.type === 'select' && field.options\n ? { type: 'string', enum: field.options }\n : { type: 'string' };\n if (field.help !== undefined) property.description = field.help;\n properties[field.name] = property;\n if (field.required) required.push(field.name);\n }\n\n return { type: 'object', properties, required, additionalProperties: false };\n}\n\nexport async function generateTypes(\n options: GenerateTypesOptions,\n): Promise<string> {\n const { manifest, registrySnapshot } = options;\n const contributes = manifest.contributes;\n\n const resolveSchema = (schema: JsonSchema): ResolvedSchema => {\n const ref = schema.$ref;\n if (typeof ref !== 'string' || ref.startsWith('#')) {\n return { schema, cwd: options.cwd };\n }\n if (options.readSchemaFile === undefined) {\n throw new TapError(\n 'TAP_SCHEMA_UNRESOLVED',\n `The manifest points at the schema file \"${ref}\", but this call passed no readSchemaFile. Run \\`tappify extension types\\`, which reads schema files from the extension directory, or supply readSchemaFile.`,\n );\n }\n return {\n schema: options.readSchemaFile(ref),\n cwd:\n options.cwd === undefined ? undefined : dirname(join(options.cwd, ref)),\n };\n };\n\n const emitter = createEmitter(resolveSchema);\n const augmentations: string[] = [];\n\n const storageEntries = Object.entries(contributes.storage ?? {});\n if (storageEntries.length > 0) {\n const lines: string[] = [];\n for (const [name, collection] of storageEntries) {\n const typeName = await emitter.declare(name, collection.schema);\n const kind = collection.singleton === true ? 'singleton' : 'collection';\n lines.push(\n ` '${name}': { kind: '${kind}'; scope: '${collection.scope}'; document: ${typeName} };`,\n );\n }\n augmentations.push(` interface TapStorageMap {\\n${lines.join('\\n')}\\n }`);\n }\n\n const procedureEntries = Object.entries(manifest.server?.procedures ?? {});\n if (procedureEntries.length > 0) {\n const lines: string[] = [];\n for (const [name, declaration] of procedureEntries) {\n const inputName = await emitter.declare(\n `${name}Input`,\n declaration.input,\n );\n const outputName = await emitter.declare(\n `${name}Output`,\n declaration.output,\n );\n lines.push(\n ` '${name}': { input: ${inputName}; output: ${outputName} };`,\n );\n }\n augmentations.push(\n ` interface TapProcedureMap {\\n${lines.join('\\n')}\\n }`,\n );\n }\n\n const actions = contributes.ai?.actions ?? [];\n if (actions.length > 0) {\n const lines: string[] = [];\n for (const action of actions) {\n const name = await emitter.declare(`${action.id}Input`, action.input);\n lines.push(` '${action.id}': { input: ${name} };`);\n }\n augmentations.push(` interface TapActionMap {\\n${lines.join('\\n')}\\n }`);\n }\n\n const tools = contributes.ai?.tools ?? [];\n if (tools.length > 0) {\n const lines: string[] = [];\n for (const tool of tools) {\n const name = await emitter.declare(`${tool.id}Input`, tool.input);\n lines.push(` '${tool.id}': { input: ${name} };`);\n }\n augmentations.push(` interface TapToolMap {\\n${lines.join('\\n')}\\n }`);\n }\n\n const prompts = (contributes.ai?.prompts ?? []).filter(\n prompt => prompt.input !== undefined,\n );\n if (prompts.length > 0) {\n const lines: string[] = [];\n for (const prompt of prompts) {\n const name = await emitter.declare(\n `${prompt.id}PromptInput`,\n prompt.input ?? { type: 'object' },\n );\n lines.push(` '${prompt.id}': { input: ${name} };`);\n }\n augmentations.push(` interface TapPromptMap {\\n${lines.join('\\n')}\\n }`);\n }\n\n const webhooks = contributes.webhooks ?? [];\n if (webhooks.length > 0) {\n const lines: string[] = [];\n for (const webhook of webhooks) {\n const name = await emitter.declare(\n `${webhook.event}Payload`,\n webhook.payload,\n );\n lines.push(` '${webhook.event}': ${name};`);\n }\n augmentations.push(` interface TapWebhookMap {\\n${lines.join('\\n')}\\n }`);\n }\n\n if (registrySnapshot !== undefined && registrySnapshot.events.length > 0) {\n const lines: string[] = [];\n for (const event of registrySnapshot.events) {\n const name = await emitter.declare(\n `${event.name}Event`,\n event.payload ?? { type: 'object' },\n );\n lines.push(` '${event.name}': ${name};`);\n }\n augmentations.push(\n ` interface TapHostEventMap {\\n${lines.join('\\n')}\\n }`,\n );\n }\n\n const telemetry = manifest.telemetry ?? [];\n if (telemetry.length > 0) {\n const lines = telemetry.map(name => ` '${name}': true;`);\n augmentations.push(\n ` interface TapTelemetryEvents {\\n${lines.join('\\n')}\\n }`,\n );\n }\n\n if (contributes.settings) {\n const name = await emitter.declare('Settings', contributes.settings.schema);\n augmentations.push(` interface TapSettings extends ${name} {}`);\n }\n\n const credentialFields = contributes.connector?.auth?.fields ?? [];\n if (credentialFields.length > 0) {\n const name = await emitter.declare(\n 'Credentials',\n credentialSchema(credentialFields),\n );\n augmentations.push(` interface TapCredentials extends ${name} {}`);\n }\n\n const declarations = emitter.declarations();\n const module =\n augmentations.length === 0\n ? \"declare module '@tappify/extension-sdk' {}\"\n : `declare module '@tappify/extension-sdk' {\\n${augmentations.join('\\n\\n')}\\n}`;\n\n return [\n GENERATED_HEADER,\n '',\n ...(declarations.length > 0 ? [declarations.join('\\n\\n'), ''] : []),\n module,\n '',\n 'export {};',\n '',\n ].join('\\n');\n}\n","/** Every code a `TapError` the SDK raises carries. */\nexport type TapErrorCode =\n | 'TAP_OUTSIDE_HOST'\n | 'TAP_SCOPE_MISSING'\n | 'TAP_UNKNOWN_COLLECTION'\n | 'TAP_UNKNOWN_PROCEDURE'\n | 'TAP_NO_PORTAL'\n | 'TAP_NO_QUERY_CLIENT'\n | 'TAP_MANIFEST_INVALID'\n | 'TAP_ENTRY_MISSING'\n | 'TAP_STYLES_UNRESOLVED'\n | 'TAP_SCHEMA_UNRESOLVED'\n | 'TAP_TOKEN_MISSING'\n | 'TAP_TOKEN_INVALID'\n | 'TAP_TOKEN_AUDIENCE'\n | 'TAP_EVENT_ID_MISSING'\n | 'TAP_BODY_INVALID'\n | 'TAP_BODY_TOO_LARGE'\n | 'TAP_ROUTE_UNKNOWN'\n | 'TAP_HANDLER_MISSING'\n | 'TAP_INTERNAL_ERROR'\n | 'TAP_WEBHOOK_REJECTED'\n | 'TAP_TEST_TARGET_INVALID';\n\n/**\n * The same codes as `TapErrorCode`, as an array to iterate or check membership\n * against at runtime.\n */\nexport const TAP_ERROR_CODES: readonly TapErrorCode[] = [\n 'TAP_OUTSIDE_HOST',\n 'TAP_SCOPE_MISSING',\n 'TAP_UNKNOWN_COLLECTION',\n 'TAP_UNKNOWN_PROCEDURE',\n 'TAP_NO_PORTAL',\n 'TAP_NO_QUERY_CLIENT',\n 'TAP_MANIFEST_INVALID',\n 'TAP_ENTRY_MISSING',\n 'TAP_STYLES_UNRESOLVED',\n 'TAP_SCHEMA_UNRESOLVED',\n 'TAP_TOKEN_MISSING',\n 'TAP_TOKEN_INVALID',\n 'TAP_TOKEN_AUDIENCE',\n 'TAP_EVENT_ID_MISSING',\n 'TAP_BODY_INVALID',\n 'TAP_BODY_TOO_LARGE',\n 'TAP_ROUTE_UNKNOWN',\n 'TAP_HANDLER_MISSING',\n 'TAP_INTERNAL_ERROR',\n 'TAP_WEBHOOK_REJECTED',\n 'TAP_TEST_TARGET_INVALID',\n];\n\nconst CODE_SET = new Set<string>(TAP_ERROR_CODES);\n\n/**\n * The error the SDK and the host raise when a call cannot be served at all.\n *\n * @remarks\n * The SDK throws it for a mount outside the host (`TAP_OUTSIDE_HOST`), a\n * collection or procedure the manifest does not declare\n * (`TAP_UNKNOWN_COLLECTION`, `TAP_UNKNOWN_PROCEDURE`), a missing portal or query\n * client, a token the server rejected, and a misused testing helper. The host\n * turns a refused read or write into `TAP_SCOPE_MISSING`. Branch on `code`, which\n * is stable; the message is prose and changes. An error your own server raised is\n * a `TapServerError` instead.\n *\n * @example\n * ```tsx\n * import { TapError, TapErrorState, useTapQuery } from '@tappify/extension-sdk';\n *\n * function Revenue() {\n * const revenue = useTapQuery({\n * kind: 'revenue',\n * range: { from: '2026-09-01', to: '2026-09-08' },\n * });\n * if (TapError.is(revenue.error) && revenue.error.code === 'TAP_SCOPE_MISSING') {\n * return <TapErrorState title=\"Revenue is not shared with this extension\" />;\n * }\n * return <span>{revenue.data?.mrr ?? 0}</span>;\n * }\n * ```\n */\nexport class TapError extends Error {\n readonly code: TapErrorCode;\n\n constructor(code: TapErrorCode, message: string) {\n super(message);\n this.name = 'TapError';\n this.code = code;\n }\n\n /**\n * Narrows an unknown value to a `TapError`, by name and by a code it\n * recognises, so it holds across module instances.\n */\n static is(value: unknown): value is TapError {\n return (\n value instanceof Error &&\n value.name === 'TapError' &&\n 'code' in value &&\n typeof value.code === 'string' &&\n CODE_SET.has(value.code)\n );\n }\n}\n\n/**\n * The error a vendor server throws to answer a Tappify call with a code and a\n * message the owner sees.\n *\n * @remarks\n * `createTappifyHandler` catches it and answers `{ error: { code, message } }`\n * with `status`, or 400 when no status was given; the host relays both to the\n * calling mount, where they arrive as the `error` of `useTapServer`. Pick a code\n * of your own and keep it stable — the SDK's own codes are `SERVER_ERROR_CODES` —\n * and write the message for the owner, who reads it on screen.\n *\n * @example\n * ```ts\n * import { TapServerError } from '@tappify/extension-sdk/server';\n *\n * function assertRange(days: number) {\n * if (days > 0) return;\n * throw new TapServerError(\n * 'RANGE_TOO_SHORT',\n * 'getSummary needs a range of at least one day. Widen the date picker, then retry.',\n * 400,\n * );\n * }\n * ```\n */\nexport class TapServerError extends Error {\n readonly code: string;\n readonly status: number | undefined;\n\n constructor(code: string, message: string, status?: number) {\n super(message);\n this.name = 'TapServerError';\n this.code = code;\n this.status = status;\n }\n\n /** The wire body the handler answers with, without the status. */\n toJSON(): { error: { code: string; message: string } } {\n return { error: { code: this.code, message: this.message } };\n }\n\n /**\n * Narrows an unknown value to a `TapServerError` by name and by carrying a\n * string `code`, so it holds across module instances.\n */\n static is(value: unknown): value is TapServerError {\n return (\n value instanceof Error &&\n value.name === 'TapServerError' &&\n 'code' in value &&\n typeof value.code === 'string'\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uCAAwB;AACxB,uBAA8B;;;AC2BvB,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,WAAW,IAAI,IAAY,eAAe;AA8BzC,IAAM,WAAN,cAAuB,MAAM;AAAA,EAGlC,YAAY,MAAoB,SAAiB;AAC/C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,GAAG,OAAmC;AAC3C,WACE,iBAAiB,SACjB,MAAM,SAAS,cACf,UAAU,SACV,OAAO,MAAM,SAAS,YACtB,SAAS,IAAI,MAAM,IAAI;AAAA,EAE3B;AACF;;;AD/FO,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAsBhC,IAAM,QAAQ;AAAA,EACZ,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,eAAe;AAAA,EACf,SAAS;AACX;AAEA,SAAS,OAAO,OAAuB;AACrC,SAAO,MACJ,MAAM,eAAe,EACrB,OAAO,UAAQ,SAAS,EAAE,EAC1B,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACxD,KAAK,EAAE;AACZ;AAaA,SAAS,cACP,eACS;AACT,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAmB,CAAC;AAE1B,SAAO;AAAA,IACL,MAAM,QAAQ,eAAe,QAAQ;AACnC,UAAI,OAAO,OAAO,aAAa;AAC/B,UAAI,SAAS;AACb,aAAO,KAAK,IAAI,IAAI,GAAG;AACrB,eAAO,GAAG,OAAO,aAAa,CAAC,GAAG,OAAO,MAAM,CAAC;AAChD,kBAAU;AAAA,MACZ;AACA,WAAK,IAAI,IAAI;AAEb,YAAM,WAAW,cAAc,MAAM;AACrC,YAAM,QAAuC;AAAA,QAC3C,GAAG,SAAS;AAAA,QACZ,OAAO;AAAA,MACT;AAEA,YAAM,OAAO,UAAM,0CAAQ,OAAO,MAAM;AAAA,QACtC,eAAe;AAAA,QACf,sBAAsB;AAAA,QACtB,6BAA6B;AAAA,QAC7B,kBAAkB;AAAA,QAClB,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,GAAI,SAAS,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,SAAS,IAAI;AAAA,MAC5D,CAAC;AAED,aAAO,KAAK,KAAK,KAAK,CAAC;AACvB,aAAO;AAAA,IACT;AAAA,IACA,eAAe;AACb,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAuC;AAC/D,QAAM,aAAyC,CAAC;AAChD,QAAM,WAAqB,CAAC;AAE5B,aAAW,SAAS,QAAQ;AAC1B,UAAM,WACJ,MAAM,SAAS,YAAY,MAAM,UAC7B,EAAE,MAAM,UAAU,MAAM,MAAM,QAAQ,IACtC,EAAE,MAAM,SAAS;AACvB,QAAI,MAAM,SAAS,OAAW,UAAS,cAAc,MAAM;AAC3D,eAAW,MAAM,IAAI,IAAI;AACzB,QAAI,MAAM,SAAU,UAAS,KAAK,MAAM,IAAI;AAAA,EAC9C;AAEA,SAAO,EAAE,MAAM,UAAU,YAAY,UAAU,sBAAsB,MAAM;AAC7E;AAEA,eAAsB,cACpB,SACiB;AACjB,QAAM,EAAE,UAAU,iBAAiB,IAAI;AACvC,QAAM,cAAc,SAAS;AAE7B,QAAM,gBAAgB,CAAC,WAAuC;AAC5D,UAAM,MAAM,OAAO;AACnB,QAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,GAAG,GAAG;AAClD,aAAO,EAAE,QAAQ,KAAK,QAAQ,IAAI;AAAA,IACpC;AACA,QAAI,QAAQ,mBAAmB,QAAW;AACxC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,2CAA2C,GAAG;AAAA,MAChD;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ,QAAQ,eAAe,GAAG;AAAA,MAClC,KACE,QAAQ,QAAQ,SAAY,aAAY,8BAAQ,uBAAK,QAAQ,KAAK,GAAG,CAAC;AAAA,IAC1E;AAAA,EACF;AAEA,QAAM,UAAU,cAAc,aAAa;AAC3C,QAAM,gBAA0B,CAAC;AAEjC,QAAM,iBAAiB,OAAO,QAAQ,YAAY,WAAW,CAAC,CAAC;AAC/D,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,QAAkB,CAAC;AACzB,eAAW,CAAC,MAAM,UAAU,KAAK,gBAAgB;AAC/C,YAAM,WAAW,MAAM,QAAQ,QAAQ,MAAM,WAAW,MAAM;AAC9D,YAAM,OAAO,WAAW,cAAc,OAAO,cAAc;AAC3D,YAAM;AAAA,QACJ,QAAQ,IAAI,eAAe,IAAI,cAAc,WAAW,KAAK,gBAAgB,QAAQ;AAAA,MACvF;AAAA,IACF;AACA,kBAAc,KAAK;AAAA,EAAgC,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO;AAAA,EAC5E;AAEA,QAAM,mBAAmB,OAAO,QAAQ,SAAS,QAAQ,cAAc,CAAC,CAAC;AACzE,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,QAAkB,CAAC;AACzB,eAAW,CAAC,MAAM,WAAW,KAAK,kBAAkB;AAClD,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,GAAG,IAAI;AAAA,QACP,YAAY;AAAA,MACd;AACA,YAAM,aAAa,MAAM,QAAQ;AAAA,QAC/B,GAAG,IAAI;AAAA,QACP,YAAY;AAAA,MACd;AACA,YAAM;AAAA,QACJ,QAAQ,IAAI,eAAe,SAAS,aAAa,UAAU;AAAA,MAC7D;AAAA,IACF;AACA,kBAAc;AAAA,MACZ;AAAA,EAAkC,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,IACpD;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,IAAI,WAAW,CAAC;AAC5C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAkB,CAAC;AACzB,eAAW,UAAU,SAAS;AAC5B,YAAM,OAAO,MAAM,QAAQ,QAAQ,GAAG,OAAO,EAAE,SAAS,OAAO,KAAK;AACpE,YAAM,KAAK,QAAQ,OAAO,EAAE,eAAe,IAAI,KAAK;AAAA,IACtD;AACA,kBAAc,KAAK;AAAA,EAA+B,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO;AAAA,EAC3E;AAEA,QAAM,QAAQ,YAAY,IAAI,SAAS,CAAC;AACxC,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,QAAkB,CAAC;AACzB,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,MAAM,QAAQ,QAAQ,GAAG,KAAK,EAAE,SAAS,KAAK,KAAK;AAChE,YAAM,KAAK,QAAQ,KAAK,EAAE,eAAe,IAAI,KAAK;AAAA,IACpD;AACA,kBAAc,KAAK;AAAA,EAA6B,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO;AAAA,EACzE;AAEA,QAAM,WAAW,YAAY,IAAI,WAAW,CAAC,GAAG;AAAA,IAC9C,YAAU,OAAO,UAAU;AAAA,EAC7B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAkB,CAAC;AACzB,eAAW,UAAU,SAAS;AAC5B,YAAM,OAAO,MAAM,QAAQ;AAAA,QACzB,GAAG,OAAO,EAAE;AAAA,QACZ,OAAO,SAAS,EAAE,MAAM,SAAS;AAAA,MACnC;AACA,YAAM,KAAK,QAAQ,OAAO,EAAE,eAAe,IAAI,KAAK;AAAA,IACtD;AACA,kBAAc,KAAK;AAAA,EAA+B,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO;AAAA,EAC3E;AAEA,QAAM,WAAW,YAAY,YAAY,CAAC;AAC1C,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,QAAkB,CAAC;AACzB,eAAW,WAAW,UAAU;AAC9B,YAAM,OAAO,MAAM,QAAQ;AAAA,QACzB,GAAG,QAAQ,KAAK;AAAA,QAChB,QAAQ;AAAA,MACV;AACA,YAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,IAAI,GAAG;AAAA,IAC/C;AACA,kBAAc,KAAK;AAAA,EAAgC,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO;AAAA,EAC5E;AAEA,MAAI,qBAAqB,UAAa,iBAAiB,OAAO,SAAS,GAAG;AACxE,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,iBAAiB,QAAQ;AAC3C,YAAM,OAAO,MAAM,QAAQ;AAAA,QACzB,GAAG,MAAM,IAAI;AAAA,QACb,MAAM,WAAW,EAAE,MAAM,SAAS;AAAA,MACpC;AACA,YAAM,KAAK,QAAQ,MAAM,IAAI,MAAM,IAAI,GAAG;AAAA,IAC5C;AACA,kBAAc;AAAA,MACZ;AAAA,EAAkC,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,IACpD;AAAA,EACF;AAEA,QAAM,YAAY,SAAS,aAAa,CAAC;AACzC,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,QAAQ,UAAU,IAAI,UAAQ,QAAQ,IAAI,UAAU;AAC1D,kBAAc;AAAA,MACZ;AAAA,EAAqC,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,IACvD;AAAA,EACF;AAEA,MAAI,YAAY,UAAU;AACxB,UAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,YAAY,SAAS,MAAM;AAC1E,kBAAc,KAAK,mCAAmC,IAAI,KAAK;AAAA,EACjE;AAEA,QAAM,mBAAmB,YAAY,WAAW,MAAM,UAAU,CAAC;AACjE,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,OAAO,MAAM,QAAQ;AAAA,MACzB;AAAA,MACA,iBAAiB,gBAAgB;AAAA,IACnC;AACA,kBAAc,KAAK,sCAAsC,IAAI,KAAK;AAAA,EACpE;AAEA,QAAM,eAAe,QAAQ,aAAa;AAC1C,QAAMA,UACJ,cAAc,WAAW,IACrB,+CACA;AAAA,EAA8C,cAAc,KAAK,MAAM,CAAC;AAAA;AAE9E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAI,aAAa,SAAS,IAAI,CAAC,aAAa,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,IACjEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;","names":["module"]}
|