@tappify/extension-sdk 2.1.0-beta.2 → 2.1.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/README.md +18 -54
- package/dist/{chunk-6HETNZJY.cjs → chunk-2DBSVKAU.cjs} +1 -1
- package/dist/{chunk-6HETNZJY.cjs.map → chunk-2DBSVKAU.cjs.map} +1 -1
- package/dist/{chunk-O357OJXL.cjs → chunk-3YWVYA42.cjs} +18 -14
- package/dist/chunk-3YWVYA42.cjs.map +1 -0
- package/dist/{chunk-GAUZYBXE.cjs → chunk-5AAPD5WV.cjs} +11 -11
- package/dist/chunk-5AAPD5WV.cjs.map +1 -0
- package/dist/{chunk-SGEYDV3K.mjs → chunk-BDCX6LRQ.mjs} +3 -3
- package/dist/chunk-BDCX6LRQ.mjs.map +1 -0
- package/dist/{chunk-KZ5NGFUP.mjs → chunk-C3YNVHBP.mjs} +7 -20
- package/dist/chunk-C3YNVHBP.mjs.map +1 -0
- package/dist/{chunk-QXD7WVKK.mjs → chunk-CSTYBKZC.mjs} +1 -1
- package/dist/chunk-CSTYBKZC.mjs.map +1 -0
- package/dist/{chunk-SWG7CNTZ.mjs → chunk-CTSZ5D7S.mjs} +5 -9
- package/dist/chunk-CTSZ5D7S.mjs.map +1 -0
- package/dist/chunk-EW54H7CR.cjs +722 -0
- package/dist/chunk-EW54H7CR.cjs.map +1 -0
- package/dist/chunk-EX3NFXDK.mjs +722 -0
- package/dist/chunk-EX3NFXDK.mjs.map +1 -0
- package/dist/{chunk-A74HCO6T.cjs → chunk-G7XZSN2Q.cjs} +18 -31
- package/dist/chunk-G7XZSN2Q.cjs.map +1 -0
- package/dist/{chunk-RBIQT75L.mjs → chunk-GG3IX52W.mjs} +2 -2
- package/dist/{chunk-SLGOHIBL.mjs → chunk-IGK2AP6J.mjs} +17 -13
- package/dist/chunk-IGK2AP6J.mjs.map +1 -0
- package/dist/{chunk-VV7ELNRW.cjs → chunk-JMUK3K47.cjs} +3 -3
- package/dist/{chunk-VV7ELNRW.cjs.map → chunk-JMUK3K47.cjs.map} +1 -1
- package/dist/{chunk-SGCYEEXD.mjs → chunk-MNDVYPEP.mjs} +2 -9
- package/dist/chunk-MNDVYPEP.mjs.map +1 -0
- package/dist/{chunk-BPCGXXMD.cjs → chunk-NFUPPCX4.cjs} +18 -22
- package/dist/chunk-NFUPPCX4.cjs.map +1 -0
- package/dist/{chunk-PRCZMOLD.cjs → chunk-OPPYEA7F.cjs} +3 -3
- package/dist/{chunk-PRCZMOLD.cjs.map → chunk-OPPYEA7F.cjs.map} +1 -1
- package/dist/{chunk-7YKH4LZN.cjs → chunk-PYJMJF44.cjs} +2 -9
- package/dist/chunk-PYJMJF44.cjs.map +1 -0
- package/dist/{chunk-QA5AL3VZ.mjs → chunk-QHM7XNRK.mjs} +2 -2
- package/dist/{chunk-QA5AL3VZ.mjs.map → chunk-QHM7XNRK.mjs.map} +1 -1
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +7 -43
- package/dist/codegen.d.ts +7 -43
- package/dist/codegen.mjs.map +1 -1
- package/dist/{constants-Bh759FUI.d.cts → constants-DJ_KgZpN.d.cts} +8 -44
- package/dist/{constants-Bh759FUI.d.ts → constants-DJ_KgZpN.d.ts} +8 -44
- package/dist/{context-mr8R5CNt.d.ts → context-Dt6xh_5t.d.cts} +4 -5
- package/dist/{context-DI0EJCRD.d.cts → context-Ml7k_V14.d.ts} +4 -5
- package/dist/{errors-Cqh0wrqt.d.ts → errors-COsBh7kd.d.cts} +2 -3
- package/dist/{errors-Cqh0wrqt.d.cts → errors-COsBh7kd.d.ts} +2 -3
- package/dist/handler-CZIlZ5vu.d.ts +227 -0
- package/dist/handler-kU9Jf36K.d.cts +227 -0
- package/dist/host.cjs +4 -4
- package/dist/host.d.cts +4 -4
- package/dist/host.d.ts +4 -4
- package/dist/host.mjs +3 -3
- package/dist/index.cjs +34 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +627 -69
- package/dist/index.d.ts +627 -69
- package/dist/index.mjs +33 -4
- package/dist/manifest.cjs +24 -136
- package/dist/manifest.cjs.map +1 -1
- package/dist/manifest.d.cts +12 -97
- package/dist/manifest.d.ts +12 -97
- package/dist/manifest.mjs +10 -122
- package/dist/manifest.mjs.map +1 -1
- package/dist/server.cjs +66 -14
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -6
- package/dist/server.d.ts +6 -6
- package/dist/server.mjs +61 -9
- package/dist/server.mjs.map +1 -1
- package/dist/styles.css +367 -0
- package/dist/testing/index.cjs +13 -72
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +10 -29
- package/dist/testing/index.d.ts +10 -29
- package/dist/testing/index.mjs +13 -72
- package/dist/testing/index.mjs.map +1 -1
- package/dist/testing/jest.cjs +5 -5
- package/dist/testing/jest.mjs +2 -2
- package/dist/testing/vitest.cjs +5 -5
- package/dist/testing/vitest.cjs.map +1 -1
- package/dist/testing/vitest.d.cts +0 -10
- package/dist/testing/vitest.d.ts +0 -10
- package/dist/testing/vitest.mjs +2 -2
- package/dist/testing/vitest.mjs.map +1 -1
- package/dist/{types-uGHrRaOj.d.ts → types-DDAGLpov.d.ts} +3 -4
- package/dist/{types-BdDaLnqs.d.cts → types-DrpQSv_2.d.cts} +3 -4
- package/dist/vite-preview.cjs +125 -294
- package/dist/vite-preview.cjs.map +1 -1
- package/dist/vite-preview.d.cts +24 -6
- package/dist/vite-preview.d.ts +24 -6
- package/dist/vite-preview.mjs +118 -287
- package/dist/vite-preview.mjs.map +1 -1
- package/dist/vite.cjs +24 -137
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +7 -43
- package/dist/vite.d.ts +7 -43
- package/dist/vite.mjs +18 -131
- package/dist/vite.mjs.map +1 -1
- package/package.json +2 -12
- package/schema/extension-v2.json +121 -440
- package/dist/chunk-2CY5HVY7.mjs +0 -59
- package/dist/chunk-2CY5HVY7.mjs.map +0 -1
- package/dist/chunk-7YKH4LZN.cjs.map +0 -1
- package/dist/chunk-A74HCO6T.cjs.map +0 -1
- package/dist/chunk-BPCGXXMD.cjs.map +0 -1
- package/dist/chunk-EB5XWQAU.cjs +0 -132
- package/dist/chunk-EB5XWQAU.cjs.map +0 -1
- package/dist/chunk-GAUZYBXE.cjs.map +0 -1
- package/dist/chunk-KZ5NGFUP.mjs.map +0 -1
- package/dist/chunk-O357OJXL.cjs.map +0 -1
- package/dist/chunk-ONJMPO3P.cjs +0 -59
- package/dist/chunk-ONJMPO3P.cjs.map +0 -1
- package/dist/chunk-QJMZRV7A.mjs +0 -132
- package/dist/chunk-QJMZRV7A.mjs.map +0 -1
- package/dist/chunk-QXD7WVKK.mjs.map +0 -1
- package/dist/chunk-SGCYEEXD.mjs.map +0 -1
- package/dist/chunk-SGEYDV3K.mjs.map +0 -1
- package/dist/chunk-SLGOHIBL.mjs.map +0 -1
- package/dist/chunk-SWG7CNTZ.mjs.map +0 -1
- package/dist/client-BO3kavn0.d.ts +0 -25
- package/dist/client-DE-vMgdO.d.cts +0 -25
- package/dist/ui/styles.css +0 -740
- package/dist/ui.cjs +0 -1018
- package/dist/ui.cjs.map +0 -1
- package/dist/ui.d.cts +0 -231
- package/dist/ui.d.ts +0 -231
- package/dist/ui.mjs +0 -1018
- package/dist/ui.mjs.map +0 -1
- package/dist/vite-preview-bootstrap.cjs +0 -66
- package/dist/vite-preview-bootstrap.cjs.map +0 -1
- package/dist/vite-preview-bootstrap.d.cts +0 -15
- package/dist/vite-preview-bootstrap.d.ts +0 -15
- package/dist/vite-preview-bootstrap.mjs +0 -66
- package/dist/vite-preview-bootstrap.mjs.map +0 -1
- package/dist/work-events-BlOVpK0k.d.ts +0 -547
- package/dist/work-events-D97EoqvS.d.cts +0 -547
- /package/dist/{chunk-RBIQT75L.mjs.map → chunk-GG3IX52W.mjs.map} +0 -0
package/dist/codegen.d.ts
CHANGED
|
@@ -28,12 +28,6 @@ declare const SCOPES: readonly [{
|
|
|
28
28
|
readonly description: "Review text, ratings and replies";
|
|
29
29
|
readonly requiresSecurityReview: false;
|
|
30
30
|
readonly requiresJustification: false;
|
|
31
|
-
}, {
|
|
32
|
-
readonly key: "review.threads:read";
|
|
33
|
-
readonly label: "Read Review threads";
|
|
34
|
-
readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
|
|
35
|
-
readonly requiresSecurityReview: false;
|
|
36
|
-
readonly requiresJustification: false;
|
|
37
31
|
}, {
|
|
38
32
|
readonly key: "crashes:read";
|
|
39
33
|
readonly label: "Read crash data";
|
|
@@ -97,7 +91,7 @@ declare const SCOPES: readonly [{
|
|
|
97
91
|
}, {
|
|
98
92
|
readonly key: "work:sync";
|
|
99
93
|
readonly label: "Sync work items";
|
|
100
|
-
readonly description: "
|
|
94
|
+
readonly description: "Two-way comments and status on created work items";
|
|
101
95
|
readonly requiresSecurityReview: false;
|
|
102
96
|
readonly requiresJustification: true;
|
|
103
97
|
}, {
|
|
@@ -261,7 +255,6 @@ interface CredentialField {
|
|
|
261
255
|
options?: string[];
|
|
262
256
|
help?: string;
|
|
263
257
|
}
|
|
264
|
-
type OAuthTokenRequestEncoding = 'form' | 'json';
|
|
265
258
|
interface ConnectorAuth {
|
|
266
259
|
method: 'none' | 'api_key' | 'oauth';
|
|
267
260
|
fields?: CredentialField[];
|
|
@@ -269,8 +262,6 @@ interface ConnectorAuth {
|
|
|
269
262
|
authorizationUrl: string;
|
|
270
263
|
tokenUrl: string;
|
|
271
264
|
scopes: string[];
|
|
272
|
-
/** The token request body encoding. When omitted, uses form encoding. */
|
|
273
|
-
tokenRequestEncoding?: OAuthTokenRequestEncoding;
|
|
274
265
|
};
|
|
275
266
|
}
|
|
276
267
|
interface DimensionDeclaration {
|
|
@@ -352,53 +343,26 @@ interface AiContribution {
|
|
|
352
343
|
prompts?: PromptDeclaration[];
|
|
353
344
|
context?: ContextDeclaration[];
|
|
354
345
|
}
|
|
355
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
356
|
-
type WorkAuth = {
|
|
357
|
-
method: 'oauth';
|
|
358
|
-
provider: string;
|
|
359
|
-
scopes: string[];
|
|
360
|
-
} | {
|
|
361
|
-
method: 'api_key';
|
|
362
|
-
fields: CredentialField[];
|
|
363
|
-
};
|
|
364
346
|
interface WorkContribution {
|
|
365
347
|
kind: 'tracker' | 'docs' | 'chat';
|
|
366
|
-
|
|
367
|
-
identity: 'install' | 'user';
|
|
368
|
-
comments: 'two-way' | 'none' | {
|
|
369
|
-
direction: WorkDirection;
|
|
370
|
-
supportsEdits: false;
|
|
371
|
-
supportsDeletes: false;
|
|
372
|
-
};
|
|
373
|
-
status?: {
|
|
374
|
-
direction: WorkDirection;
|
|
375
|
-
webhook?: string;
|
|
376
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
377
|
-
};
|
|
378
|
-
attachments: ('image' | 'link')[];
|
|
379
|
-
auth: WorkAuth;
|
|
380
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
381
|
-
container?: {
|
|
348
|
+
container: {
|
|
382
349
|
label: string;
|
|
383
350
|
list: string;
|
|
384
351
|
};
|
|
385
|
-
|
|
386
|
-
fields
|
|
352
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
353
|
+
fields: {
|
|
387
354
|
priority?: string[];
|
|
388
355
|
labels?: boolean;
|
|
389
356
|
assignee?: boolean;
|
|
390
357
|
required: string[];
|
|
391
358
|
};
|
|
392
|
-
|
|
393
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
394
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
395
|
-
container: NonNullable<WorkContribution['container']>;
|
|
396
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
359
|
+
attachments: ('image' | 'link')[];
|
|
397
360
|
comments: 'two-way' | 'none';
|
|
398
361
|
status?: {
|
|
399
362
|
webhook: string;
|
|
400
363
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
401
364
|
};
|
|
365
|
+
identity: 'user' | 'install';
|
|
402
366
|
}
|
|
403
367
|
interface ExtensionListing {
|
|
404
368
|
longDescription?: string;
|
|
@@ -431,7 +395,7 @@ interface ExtensionManifest {
|
|
|
431
395
|
connector?: ConnectorContribution;
|
|
432
396
|
webhooks?: WebhookContribution[];
|
|
433
397
|
ai?: AiContribution;
|
|
434
|
-
work?: WorkContribution
|
|
398
|
+
work?: WorkContribution;
|
|
435
399
|
};
|
|
436
400
|
server?: {
|
|
437
401
|
baseUrl: string;
|
package/dist/codegen.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/codegen/generate.ts","../src/client/errors.ts"],"sourcesContent":["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, useTapQuery } from '@tappify/extension-sdk';\n * import { ErrorState } from '@tappify/extension-sdk/ui';\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 <ErrorState 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":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/codegen/generate.ts","../src/client/errors.ts"],"sourcesContent":["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":"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","names":[]}
|
|
@@ -75,7 +75,6 @@ interface CredentialField {
|
|
|
75
75
|
options?: string[];
|
|
76
76
|
help?: string;
|
|
77
77
|
}
|
|
78
|
-
type OAuthTokenRequestEncoding = 'form' | 'json';
|
|
79
78
|
interface ConnectorAuth {
|
|
80
79
|
method: 'none' | 'api_key' | 'oauth';
|
|
81
80
|
fields?: CredentialField[];
|
|
@@ -83,8 +82,6 @@ interface ConnectorAuth {
|
|
|
83
82
|
authorizationUrl: string;
|
|
84
83
|
tokenUrl: string;
|
|
85
84
|
scopes: string[];
|
|
86
|
-
/** The token request body encoding. When omitted, uses form encoding. */
|
|
87
|
-
tokenRequestEncoding?: OAuthTokenRequestEncoding;
|
|
88
85
|
};
|
|
89
86
|
}
|
|
90
87
|
interface DimensionDeclaration {
|
|
@@ -166,53 +163,26 @@ interface AiContribution {
|
|
|
166
163
|
prompts?: PromptDeclaration[];
|
|
167
164
|
context?: ContextDeclaration[];
|
|
168
165
|
}
|
|
169
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
170
|
-
type WorkAuth = {
|
|
171
|
-
method: 'oauth';
|
|
172
|
-
provider: string;
|
|
173
|
-
scopes: string[];
|
|
174
|
-
} | {
|
|
175
|
-
method: 'api_key';
|
|
176
|
-
fields: CredentialField[];
|
|
177
|
-
};
|
|
178
166
|
interface WorkContribution {
|
|
179
167
|
kind: 'tracker' | 'docs' | 'chat';
|
|
180
|
-
|
|
181
|
-
identity: 'install' | 'user';
|
|
182
|
-
comments: 'two-way' | 'none' | {
|
|
183
|
-
direction: WorkDirection;
|
|
184
|
-
supportsEdits: false;
|
|
185
|
-
supportsDeletes: false;
|
|
186
|
-
};
|
|
187
|
-
status?: {
|
|
188
|
-
direction: WorkDirection;
|
|
189
|
-
webhook?: string;
|
|
190
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
191
|
-
};
|
|
192
|
-
attachments: ('image' | 'link')[];
|
|
193
|
-
auth: WorkAuth;
|
|
194
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
195
|
-
container?: {
|
|
168
|
+
container: {
|
|
196
169
|
label: string;
|
|
197
170
|
list: string;
|
|
198
171
|
};
|
|
199
|
-
|
|
200
|
-
fields
|
|
172
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
173
|
+
fields: {
|
|
201
174
|
priority?: string[];
|
|
202
175
|
labels?: boolean;
|
|
203
176
|
assignee?: boolean;
|
|
204
177
|
required: string[];
|
|
205
178
|
};
|
|
206
|
-
|
|
207
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
208
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
209
|
-
container: NonNullable<WorkContribution['container']>;
|
|
210
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
179
|
+
attachments: ('image' | 'link')[];
|
|
211
180
|
comments: 'two-way' | 'none';
|
|
212
181
|
status?: {
|
|
213
182
|
webhook: string;
|
|
214
183
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
215
184
|
};
|
|
185
|
+
identity: 'user' | 'install';
|
|
216
186
|
}
|
|
217
187
|
interface ExtensionListing {
|
|
218
188
|
longDescription?: string;
|
|
@@ -245,7 +215,7 @@ interface ExtensionManifest {
|
|
|
245
215
|
connector?: ConnectorContribution;
|
|
246
216
|
webhooks?: WebhookContribution[];
|
|
247
217
|
ai?: AiContribution;
|
|
248
|
-
work?: WorkContribution
|
|
218
|
+
work?: WorkContribution;
|
|
249
219
|
};
|
|
250
220
|
server?: {
|
|
251
221
|
baseUrl: string;
|
|
@@ -307,12 +277,6 @@ declare const SCOPES: readonly [{
|
|
|
307
277
|
readonly description: "Review text, ratings and replies";
|
|
308
278
|
readonly requiresSecurityReview: false;
|
|
309
279
|
readonly requiresJustification: false;
|
|
310
|
-
}, {
|
|
311
|
-
readonly key: "review.threads:read";
|
|
312
|
-
readonly label: "Read Review threads";
|
|
313
|
-
readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
|
|
314
|
-
readonly requiresSecurityReview: false;
|
|
315
|
-
readonly requiresJustification: false;
|
|
316
280
|
}, {
|
|
317
281
|
readonly key: "crashes:read";
|
|
318
282
|
readonly label: "Read crash data";
|
|
@@ -376,7 +340,7 @@ declare const SCOPES: readonly [{
|
|
|
376
340
|
}, {
|
|
377
341
|
readonly key: "work:sync";
|
|
378
342
|
readonly label: "Sync work items";
|
|
379
|
-
readonly description: "
|
|
343
|
+
readonly description: "Two-way comments and status on created work items";
|
|
380
344
|
readonly requiresSecurityReview: false;
|
|
381
345
|
readonly requiresJustification: true;
|
|
382
346
|
}, {
|
|
@@ -482,4 +446,4 @@ declare const findPage: (key: string) => PageDefinition | undefined;
|
|
|
482
446
|
declare const findTable: (key: string) => TableDefinition | undefined;
|
|
483
447
|
declare const slotsForPage: (page: string) => readonly SlotId[];
|
|
484
448
|
|
|
485
|
-
export {
|
|
449
|
+
export { TABLES as $, type ActionDeclaration as A, type BannerContribution as B, CARD_KEYS as C, type DataQueryKind as D, type ExtensionManifest as E, type PageDefinition as F, type ProcedureDeclaration as G, type HostEventName as H, type PromptDeclaration as I, type JsonSchema as J, KINDS as K, SCOPES as L, type ManifestValidation as M, SCOPE_KEYS as N, SERVED_SDK_MAJORS as O, PAGES as P, QUERY_SCOPES as Q, type RowActionContribution as R, type ScopeKey as S, SLOTS as T, type UiContributionRef as U, type ScopeDefinition as V, type ScopeEntry as W, type SeriesContribution as X, type SettingsContribution as Y, type SkillDeclaration as Z, type StorageCollection as _, type HostPage as a, TABLE_KEYS as a0, type TabContribution as a1, type TableDefinition as a2, type ToolDeclaration as a3, type WebhookContribution as a4, type WidgetContribution as a5, type WorkContribution as a6, findPage as a7, findScope as a8, findTable as a9, slotsForPage as aa, type SlotId as b, type ExposableKind as c, type AiContribution as d, CATEGORIES as e, CHARTS as f, type ConnectorAuth as g, type ConnectorContribution as h, type ContextDeclaration as i, type ContributionKind as j, type CredentialField as k, type DimensionDeclaration as l, EVENTS as m, type ExtensionCategory as n, type ExtensionInstallScope as o, type ExtensionListing as p, type ExtensionVisibility as q, type HostChart as r, type HostTable as s, type KnowledgeDeclaration as t, type ManifestIssue as u, type MarkerContribution as v, type MentionDeclaration as w, type MetricDeclaration as x, PAGE_KEYS as y, type PageContribution as z };
|
|
@@ -75,7 +75,6 @@ interface CredentialField {
|
|
|
75
75
|
options?: string[];
|
|
76
76
|
help?: string;
|
|
77
77
|
}
|
|
78
|
-
type OAuthTokenRequestEncoding = 'form' | 'json';
|
|
79
78
|
interface ConnectorAuth {
|
|
80
79
|
method: 'none' | 'api_key' | 'oauth';
|
|
81
80
|
fields?: CredentialField[];
|
|
@@ -83,8 +82,6 @@ interface ConnectorAuth {
|
|
|
83
82
|
authorizationUrl: string;
|
|
84
83
|
tokenUrl: string;
|
|
85
84
|
scopes: string[];
|
|
86
|
-
/** The token request body encoding. When omitted, uses form encoding. */
|
|
87
|
-
tokenRequestEncoding?: OAuthTokenRequestEncoding;
|
|
88
85
|
};
|
|
89
86
|
}
|
|
90
87
|
interface DimensionDeclaration {
|
|
@@ -166,53 +163,26 @@ interface AiContribution {
|
|
|
166
163
|
prompts?: PromptDeclaration[];
|
|
167
164
|
context?: ContextDeclaration[];
|
|
168
165
|
}
|
|
169
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
170
|
-
type WorkAuth = {
|
|
171
|
-
method: 'oauth';
|
|
172
|
-
provider: string;
|
|
173
|
-
scopes: string[];
|
|
174
|
-
} | {
|
|
175
|
-
method: 'api_key';
|
|
176
|
-
fields: CredentialField[];
|
|
177
|
-
};
|
|
178
166
|
interface WorkContribution {
|
|
179
167
|
kind: 'tracker' | 'docs' | 'chat';
|
|
180
|
-
|
|
181
|
-
identity: 'install' | 'user';
|
|
182
|
-
comments: 'two-way' | 'none' | {
|
|
183
|
-
direction: WorkDirection;
|
|
184
|
-
supportsEdits: false;
|
|
185
|
-
supportsDeletes: false;
|
|
186
|
-
};
|
|
187
|
-
status?: {
|
|
188
|
-
direction: WorkDirection;
|
|
189
|
-
webhook?: string;
|
|
190
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
191
|
-
};
|
|
192
|
-
attachments: ('image' | 'link')[];
|
|
193
|
-
auth: WorkAuth;
|
|
194
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
195
|
-
container?: {
|
|
168
|
+
container: {
|
|
196
169
|
label: string;
|
|
197
170
|
list: string;
|
|
198
171
|
};
|
|
199
|
-
|
|
200
|
-
fields
|
|
172
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
173
|
+
fields: {
|
|
201
174
|
priority?: string[];
|
|
202
175
|
labels?: boolean;
|
|
203
176
|
assignee?: boolean;
|
|
204
177
|
required: string[];
|
|
205
178
|
};
|
|
206
|
-
|
|
207
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
208
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
209
|
-
container: NonNullable<WorkContribution['container']>;
|
|
210
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
179
|
+
attachments: ('image' | 'link')[];
|
|
211
180
|
comments: 'two-way' | 'none';
|
|
212
181
|
status?: {
|
|
213
182
|
webhook: string;
|
|
214
183
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
215
184
|
};
|
|
185
|
+
identity: 'user' | 'install';
|
|
216
186
|
}
|
|
217
187
|
interface ExtensionListing {
|
|
218
188
|
longDescription?: string;
|
|
@@ -245,7 +215,7 @@ interface ExtensionManifest {
|
|
|
245
215
|
connector?: ConnectorContribution;
|
|
246
216
|
webhooks?: WebhookContribution[];
|
|
247
217
|
ai?: AiContribution;
|
|
248
|
-
work?: WorkContribution
|
|
218
|
+
work?: WorkContribution;
|
|
249
219
|
};
|
|
250
220
|
server?: {
|
|
251
221
|
baseUrl: string;
|
|
@@ -307,12 +277,6 @@ declare const SCOPES: readonly [{
|
|
|
307
277
|
readonly description: "Review text, ratings and replies";
|
|
308
278
|
readonly requiresSecurityReview: false;
|
|
309
279
|
readonly requiresJustification: false;
|
|
310
|
-
}, {
|
|
311
|
-
readonly key: "review.threads:read";
|
|
312
|
-
readonly label: "Read Review threads";
|
|
313
|
-
readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
|
|
314
|
-
readonly requiresSecurityReview: false;
|
|
315
|
-
readonly requiresJustification: false;
|
|
316
280
|
}, {
|
|
317
281
|
readonly key: "crashes:read";
|
|
318
282
|
readonly label: "Read crash data";
|
|
@@ -376,7 +340,7 @@ declare const SCOPES: readonly [{
|
|
|
376
340
|
}, {
|
|
377
341
|
readonly key: "work:sync";
|
|
378
342
|
readonly label: "Sync work items";
|
|
379
|
-
readonly description: "
|
|
343
|
+
readonly description: "Two-way comments and status on created work items";
|
|
380
344
|
readonly requiresSecurityReview: false;
|
|
381
345
|
readonly requiresJustification: true;
|
|
382
346
|
}, {
|
|
@@ -482,4 +446,4 @@ declare const findPage: (key: string) => PageDefinition | undefined;
|
|
|
482
446
|
declare const findTable: (key: string) => TableDefinition | undefined;
|
|
483
447
|
declare const slotsForPage: (page: string) => readonly SlotId[];
|
|
484
448
|
|
|
485
|
-
export {
|
|
449
|
+
export { TABLES as $, type ActionDeclaration as A, type BannerContribution as B, CARD_KEYS as C, type DataQueryKind as D, type ExtensionManifest as E, type PageDefinition as F, type ProcedureDeclaration as G, type HostEventName as H, type PromptDeclaration as I, type JsonSchema as J, KINDS as K, SCOPES as L, type ManifestValidation as M, SCOPE_KEYS as N, SERVED_SDK_MAJORS as O, PAGES as P, QUERY_SCOPES as Q, type RowActionContribution as R, type ScopeKey as S, SLOTS as T, type UiContributionRef as U, type ScopeDefinition as V, type ScopeEntry as W, type SeriesContribution as X, type SettingsContribution as Y, type SkillDeclaration as Z, type StorageCollection as _, type HostPage as a, TABLE_KEYS as a0, type TabContribution as a1, type TableDefinition as a2, type ToolDeclaration as a3, type WebhookContribution as a4, type WidgetContribution as a5, type WorkContribution as a6, findPage as a7, findScope as a8, findTable as a9, slotsForPage as aa, type SlotId as b, type ExposableKind as c, type AiContribution as d, CATEGORIES as e, CHARTS as f, type ConnectorAuth as g, type ConnectorContribution as h, type ContextDeclaration as i, type ContributionKind as j, type CredentialField as k, type DimensionDeclaration as l, EVENTS as m, type ExtensionCategory as n, type ExtensionInstallScope as o, type ExtensionListing as p, type ExtensionVisibility as q, type HostChart as r, type HostTable as s, type KnowledgeDeclaration as t, type ManifestIssue as u, type MarkerContribution as v, type MentionDeclaration as w, type MetricDeclaration as x, PAGE_KEYS as y, type PageContribution as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context } from 'react';
|
|
2
|
-
import { T as Tap } from './types-
|
|
2
|
+
import { T as Tap } from './types-DrpQSv_2.cjs';
|
|
3
3
|
|
|
4
4
|
declare const TapContext: Context<Tap | null>;
|
|
5
5
|
/**
|
|
@@ -13,15 +13,14 @@ declare const TapContext: Context<Tap | null>;
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```tsx
|
|
16
|
-
* import { useTap } from '@tappify/extension-sdk';
|
|
17
|
-
* import { Button } from '@tappify/extension-sdk/ui';
|
|
16
|
+
* import { TapButton, useTap } from '@tappify/extension-sdk';
|
|
18
17
|
*
|
|
19
18
|
* function CopyId() {
|
|
20
19
|
* const tap = useTap();
|
|
21
20
|
* return (
|
|
22
|
-
* <
|
|
21
|
+
* <TapButton onClick={() => void tap.ui.copy(tap.project.id)}>
|
|
23
22
|
* Copy project id
|
|
24
|
-
* </
|
|
23
|
+
* </TapButton>
|
|
25
24
|
* );
|
|
26
25
|
* }
|
|
27
26
|
* ```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context } from 'react';
|
|
2
|
-
import { T as Tap } from './types-
|
|
2
|
+
import { T as Tap } from './types-DDAGLpov.js';
|
|
3
3
|
|
|
4
4
|
declare const TapContext: Context<Tap | null>;
|
|
5
5
|
/**
|
|
@@ -13,15 +13,14 @@ declare const TapContext: Context<Tap | null>;
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```tsx
|
|
16
|
-
* import { useTap } from '@tappify/extension-sdk';
|
|
17
|
-
* import { Button } from '@tappify/extension-sdk/ui';
|
|
16
|
+
* import { TapButton, useTap } from '@tappify/extension-sdk';
|
|
18
17
|
*
|
|
19
18
|
* function CopyId() {
|
|
20
19
|
* const tap = useTap();
|
|
21
20
|
* return (
|
|
22
|
-
* <
|
|
21
|
+
* <TapButton onClick={() => void tap.ui.copy(tap.project.id)}>
|
|
23
22
|
* Copy project id
|
|
24
|
-
* </
|
|
23
|
+
* </TapButton>
|
|
25
24
|
* );
|
|
26
25
|
* }
|
|
27
26
|
* ```
|
|
@@ -19,8 +19,7 @@ declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* ```tsx
|
|
22
|
-
* import { TapError, useTapQuery } from '@tappify/extension-sdk';
|
|
23
|
-
* import { ErrorState } from '@tappify/extension-sdk/ui';
|
|
22
|
+
* import { TapError, TapErrorState, useTapQuery } from '@tappify/extension-sdk';
|
|
24
23
|
*
|
|
25
24
|
* function Revenue() {
|
|
26
25
|
* const revenue = useTapQuery({
|
|
@@ -28,7 +27,7 @@ declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
|
28
27
|
* range: { from: '2026-09-01', to: '2026-09-08' },
|
|
29
28
|
* });
|
|
30
29
|
* if (TapError.is(revenue.error) && revenue.error.code === 'TAP_SCOPE_MISSING') {
|
|
31
|
-
* return <
|
|
30
|
+
* return <TapErrorState title="Revenue is not shared with this extension" />;
|
|
32
31
|
* }
|
|
33
32
|
* return <span>{revenue.data?.mrr ?? 0}</span>;
|
|
34
33
|
* }
|
|
@@ -19,8 +19,7 @@ declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* ```tsx
|
|
22
|
-
* import { TapError, useTapQuery } from '@tappify/extension-sdk';
|
|
23
|
-
* import { ErrorState } from '@tappify/extension-sdk/ui';
|
|
22
|
+
* import { TapError, TapErrorState, useTapQuery } from '@tappify/extension-sdk';
|
|
24
23
|
*
|
|
25
24
|
* function Revenue() {
|
|
26
25
|
* const revenue = useTapQuery({
|
|
@@ -28,7 +27,7 @@ declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
|
28
27
|
* range: { from: '2026-09-01', to: '2026-09-08' },
|
|
29
28
|
* });
|
|
30
29
|
* if (TapError.is(revenue.error) && revenue.error.code === 'TAP_SCOPE_MISSING') {
|
|
31
|
-
* return <
|
|
30
|
+
* return <TapErrorState title="Revenue is not shared with this extension" />;
|
|
32
31
|
* }
|
|
33
32
|
* return <span>{revenue.data?.mrr ?? 0}</span>;
|
|
34
33
|
* }
|