@tappify/extension-sdk 2.1.0-beta.1 → 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 -40
- package/dist/codegen.d.ts +7 -40
- package/dist/codegen.mjs.map +1 -1
- package/dist/{constants-BAimnqOK.d.cts → constants-DJ_KgZpN.d.cts} +8 -41
- package/dist/{constants-BAimnqOK.d.ts → constants-DJ_KgZpN.d.ts} +8 -41
- package/dist/{context-Cr93B05o.d.ts → context-Dt6xh_5t.d.cts} +4 -5
- package/dist/{context-DJ3REtdT.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 +23 -132
- package/dist/manifest.cjs.map +1 -1
- package/dist/manifest.d.cts +12 -93
- package/dist/manifest.d.ts +12 -93
- package/dist/manifest.mjs +9 -118
- 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-BYGcp5pZ.d.ts → types-DDAGLpov.d.ts} +3 -4
- package/dist/{types-I1JOZyI_.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 +23 -133
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +7 -40
- package/dist/vite.d.ts +7 -40
- package/dist/vite.mjs +17 -127
- package/dist/vite.mjs.map +1 -1
- package/package.json +2 -12
- package/schema/extension-v2.json +121 -432
- 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-CV1qzQgx.d.cts +0 -25
- package/dist/client-CnlSHDWE.d.ts +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-DB3WR468.d.ts +0 -547
- package/dist/work-events-Dxe7Djdy.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
|
}, {
|
|
@@ -349,53 +343,26 @@ interface AiContribution {
|
|
|
349
343
|
prompts?: PromptDeclaration[];
|
|
350
344
|
context?: ContextDeclaration[];
|
|
351
345
|
}
|
|
352
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
353
|
-
type WorkAuth = {
|
|
354
|
-
method: 'oauth';
|
|
355
|
-
provider: string;
|
|
356
|
-
scopes: string[];
|
|
357
|
-
} | {
|
|
358
|
-
method: 'api_key';
|
|
359
|
-
fields: CredentialField[];
|
|
360
|
-
};
|
|
361
346
|
interface WorkContribution {
|
|
362
347
|
kind: 'tracker' | 'docs' | 'chat';
|
|
363
|
-
|
|
364
|
-
identity: 'install' | 'user';
|
|
365
|
-
comments: 'two-way' | 'none' | {
|
|
366
|
-
direction: WorkDirection;
|
|
367
|
-
supportsEdits: false;
|
|
368
|
-
supportsDeletes: false;
|
|
369
|
-
};
|
|
370
|
-
status?: {
|
|
371
|
-
direction: WorkDirection;
|
|
372
|
-
webhook?: string;
|
|
373
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
374
|
-
};
|
|
375
|
-
attachments: ('image' | 'link')[];
|
|
376
|
-
auth: WorkAuth;
|
|
377
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
378
|
-
container?: {
|
|
348
|
+
container: {
|
|
379
349
|
label: string;
|
|
380
350
|
list: string;
|
|
381
351
|
};
|
|
382
|
-
|
|
383
|
-
fields
|
|
352
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
353
|
+
fields: {
|
|
384
354
|
priority?: string[];
|
|
385
355
|
labels?: boolean;
|
|
386
356
|
assignee?: boolean;
|
|
387
357
|
required: string[];
|
|
388
358
|
};
|
|
389
|
-
|
|
390
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
391
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
392
|
-
container: NonNullable<WorkContribution['container']>;
|
|
393
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
359
|
+
attachments: ('image' | 'link')[];
|
|
394
360
|
comments: 'two-way' | 'none';
|
|
395
361
|
status?: {
|
|
396
362
|
webhook: string;
|
|
397
363
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
398
364
|
};
|
|
365
|
+
identity: 'user' | 'install';
|
|
399
366
|
}
|
|
400
367
|
interface ExtensionListing {
|
|
401
368
|
longDescription?: string;
|
|
@@ -428,7 +395,7 @@ interface ExtensionManifest {
|
|
|
428
395
|
connector?: ConnectorContribution;
|
|
429
396
|
webhooks?: WebhookContribution[];
|
|
430
397
|
ai?: AiContribution;
|
|
431
|
-
work?: WorkContribution
|
|
398
|
+
work?: WorkContribution;
|
|
432
399
|
};
|
|
433
400
|
server?: {
|
|
434
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":[]}
|
|
@@ -163,53 +163,26 @@ interface AiContribution {
|
|
|
163
163
|
prompts?: PromptDeclaration[];
|
|
164
164
|
context?: ContextDeclaration[];
|
|
165
165
|
}
|
|
166
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
167
|
-
type WorkAuth = {
|
|
168
|
-
method: 'oauth';
|
|
169
|
-
provider: string;
|
|
170
|
-
scopes: string[];
|
|
171
|
-
} | {
|
|
172
|
-
method: 'api_key';
|
|
173
|
-
fields: CredentialField[];
|
|
174
|
-
};
|
|
175
166
|
interface WorkContribution {
|
|
176
167
|
kind: 'tracker' | 'docs' | 'chat';
|
|
177
|
-
|
|
178
|
-
identity: 'install' | 'user';
|
|
179
|
-
comments: 'two-way' | 'none' | {
|
|
180
|
-
direction: WorkDirection;
|
|
181
|
-
supportsEdits: false;
|
|
182
|
-
supportsDeletes: false;
|
|
183
|
-
};
|
|
184
|
-
status?: {
|
|
185
|
-
direction: WorkDirection;
|
|
186
|
-
webhook?: string;
|
|
187
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
188
|
-
};
|
|
189
|
-
attachments: ('image' | 'link')[];
|
|
190
|
-
auth: WorkAuth;
|
|
191
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
192
|
-
container?: {
|
|
168
|
+
container: {
|
|
193
169
|
label: string;
|
|
194
170
|
list: string;
|
|
195
171
|
};
|
|
196
|
-
|
|
197
|
-
fields
|
|
172
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
173
|
+
fields: {
|
|
198
174
|
priority?: string[];
|
|
199
175
|
labels?: boolean;
|
|
200
176
|
assignee?: boolean;
|
|
201
177
|
required: string[];
|
|
202
178
|
};
|
|
203
|
-
|
|
204
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
205
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
206
|
-
container: NonNullable<WorkContribution['container']>;
|
|
207
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
179
|
+
attachments: ('image' | 'link')[];
|
|
208
180
|
comments: 'two-way' | 'none';
|
|
209
181
|
status?: {
|
|
210
182
|
webhook: string;
|
|
211
183
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
212
184
|
};
|
|
185
|
+
identity: 'user' | 'install';
|
|
213
186
|
}
|
|
214
187
|
interface ExtensionListing {
|
|
215
188
|
longDescription?: string;
|
|
@@ -242,7 +215,7 @@ interface ExtensionManifest {
|
|
|
242
215
|
connector?: ConnectorContribution;
|
|
243
216
|
webhooks?: WebhookContribution[];
|
|
244
217
|
ai?: AiContribution;
|
|
245
|
-
work?: WorkContribution
|
|
218
|
+
work?: WorkContribution;
|
|
246
219
|
};
|
|
247
220
|
server?: {
|
|
248
221
|
baseUrl: string;
|
|
@@ -304,12 +277,6 @@ declare const SCOPES: readonly [{
|
|
|
304
277
|
readonly description: "Review text, ratings and replies";
|
|
305
278
|
readonly requiresSecurityReview: false;
|
|
306
279
|
readonly requiresJustification: false;
|
|
307
|
-
}, {
|
|
308
|
-
readonly key: "review.threads:read";
|
|
309
|
-
readonly label: "Read Review threads";
|
|
310
|
-
readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
|
|
311
|
-
readonly requiresSecurityReview: false;
|
|
312
|
-
readonly requiresJustification: false;
|
|
313
280
|
}, {
|
|
314
281
|
readonly key: "crashes:read";
|
|
315
282
|
readonly label: "Read crash data";
|
|
@@ -373,7 +340,7 @@ declare const SCOPES: readonly [{
|
|
|
373
340
|
}, {
|
|
374
341
|
readonly key: "work:sync";
|
|
375
342
|
readonly label: "Sync work items";
|
|
376
|
-
readonly description: "
|
|
343
|
+
readonly description: "Two-way comments and status on created work items";
|
|
377
344
|
readonly requiresSecurityReview: false;
|
|
378
345
|
readonly requiresJustification: true;
|
|
379
346
|
}, {
|
|
@@ -479,4 +446,4 @@ declare const findPage: (key: string) => PageDefinition | undefined;
|
|
|
479
446
|
declare const findTable: (key: string) => TableDefinition | undefined;
|
|
480
447
|
declare const slotsForPage: (page: string) => readonly SlotId[];
|
|
481
448
|
|
|
482
|
-
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 };
|
|
@@ -163,53 +163,26 @@ interface AiContribution {
|
|
|
163
163
|
prompts?: PromptDeclaration[];
|
|
164
164
|
context?: ContextDeclaration[];
|
|
165
165
|
}
|
|
166
|
-
type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
|
|
167
|
-
type WorkAuth = {
|
|
168
|
-
method: 'oauth';
|
|
169
|
-
provider: string;
|
|
170
|
-
scopes: string[];
|
|
171
|
-
} | {
|
|
172
|
-
method: 'api_key';
|
|
173
|
-
fields: CredentialField[];
|
|
174
|
-
};
|
|
175
166
|
interface WorkContribution {
|
|
176
167
|
kind: 'tracker' | 'docs' | 'chat';
|
|
177
|
-
|
|
178
|
-
identity: 'install' | 'user';
|
|
179
|
-
comments: 'two-way' | 'none' | {
|
|
180
|
-
direction: WorkDirection;
|
|
181
|
-
supportsEdits: false;
|
|
182
|
-
supportsDeletes: false;
|
|
183
|
-
};
|
|
184
|
-
status?: {
|
|
185
|
-
direction: WorkDirection;
|
|
186
|
-
webhook?: string;
|
|
187
|
-
map?: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
188
|
-
};
|
|
189
|
-
attachments: ('image' | 'link')[];
|
|
190
|
-
auth: WorkAuth;
|
|
191
|
-
/** @deprecated resolved dynamically by describe_container */
|
|
192
|
-
container?: {
|
|
168
|
+
container: {
|
|
193
169
|
label: string;
|
|
194
170
|
list: string;
|
|
195
171
|
};
|
|
196
|
-
|
|
197
|
-
fields
|
|
172
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
173
|
+
fields: {
|
|
198
174
|
priority?: string[];
|
|
199
175
|
labels?: boolean;
|
|
200
176
|
assignee?: boolean;
|
|
201
177
|
required: string[];
|
|
202
178
|
};
|
|
203
|
-
|
|
204
|
-
/** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
|
|
205
|
-
interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
|
|
206
|
-
container: NonNullable<WorkContribution['container']>;
|
|
207
|
-
fields: NonNullable<WorkContribution['fields']>;
|
|
179
|
+
attachments: ('image' | 'link')[];
|
|
208
180
|
comments: 'two-way' | 'none';
|
|
209
181
|
status?: {
|
|
210
182
|
webhook: string;
|
|
211
183
|
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
212
184
|
};
|
|
185
|
+
identity: 'user' | 'install';
|
|
213
186
|
}
|
|
214
187
|
interface ExtensionListing {
|
|
215
188
|
longDescription?: string;
|
|
@@ -242,7 +215,7 @@ interface ExtensionManifest {
|
|
|
242
215
|
connector?: ConnectorContribution;
|
|
243
216
|
webhooks?: WebhookContribution[];
|
|
244
217
|
ai?: AiContribution;
|
|
245
|
-
work?: WorkContribution
|
|
218
|
+
work?: WorkContribution;
|
|
246
219
|
};
|
|
247
220
|
server?: {
|
|
248
221
|
baseUrl: string;
|
|
@@ -304,12 +277,6 @@ declare const SCOPES: readonly [{
|
|
|
304
277
|
readonly description: "Review text, ratings and replies";
|
|
305
278
|
readonly requiresSecurityReview: false;
|
|
306
279
|
readonly requiresJustification: false;
|
|
307
|
-
}, {
|
|
308
|
-
readonly key: "review.threads:read";
|
|
309
|
-
readonly label: "Read Review threads";
|
|
310
|
-
readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
|
|
311
|
-
readonly requiresSecurityReview: false;
|
|
312
|
-
readonly requiresJustification: false;
|
|
313
280
|
}, {
|
|
314
281
|
readonly key: "crashes:read";
|
|
315
282
|
readonly label: "Read crash data";
|
|
@@ -373,7 +340,7 @@ declare const SCOPES: readonly [{
|
|
|
373
340
|
}, {
|
|
374
341
|
readonly key: "work:sync";
|
|
375
342
|
readonly label: "Sync work items";
|
|
376
|
-
readonly description: "
|
|
343
|
+
readonly description: "Two-way comments and status on created work items";
|
|
377
344
|
readonly requiresSecurityReview: false;
|
|
378
345
|
readonly requiresJustification: true;
|
|
379
346
|
}, {
|
|
@@ -479,4 +446,4 @@ declare const findPage: (key: string) => PageDefinition | undefined;
|
|
|
479
446
|
declare const findTable: (key: string) => TableDefinition | undefined;
|
|
480
447
|
declare const slotsForPage: (page: string) => readonly SlotId[];
|
|
481
448
|
|
|
482
|
-
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
|
* }
|