@tappify/extension-sdk 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/chunk-2DBSVKAU.cjs +65 -0
- package/dist/chunk-2DBSVKAU.cjs.map +1 -0
- package/dist/chunk-3YWVYA42.cjs +142 -0
- package/dist/chunk-3YWVYA42.cjs.map +1 -0
- package/dist/chunk-4C5Z3CIK.mjs +26 -0
- package/dist/chunk-4C5Z3CIK.mjs.map +1 -0
- package/dist/chunk-5AAPD5WV.cjs +250 -0
- package/dist/chunk-5AAPD5WV.cjs.map +1 -0
- package/dist/chunk-7KIKOH5H.cjs +26 -0
- package/dist/chunk-7KIKOH5H.cjs.map +1 -0
- package/dist/chunk-BDCX6LRQ.mjs +250 -0
- package/dist/chunk-BDCX6LRQ.mjs.map +1 -0
- package/dist/chunk-CSTYBKZC.mjs +65 -0
- package/dist/chunk-CSTYBKZC.mjs.map +1 -0
- package/dist/chunk-IGK2AP6J.mjs +142 -0
- package/dist/chunk-IGK2AP6J.mjs.map +1 -0
- package/dist/chunk-MNDVYPEP.mjs +302 -0
- package/dist/chunk-MNDVYPEP.mjs.map +1 -0
- package/dist/chunk-OPPYEA7F.cjs +33 -0
- package/dist/chunk-OPPYEA7F.cjs.map +1 -0
- package/dist/chunk-PYJMJF44.cjs +302 -0
- package/dist/chunk-PYJMJF44.cjs.map +1 -0
- package/dist/chunk-QHM7XNRK.mjs +33 -0
- package/dist/chunk-QHM7XNRK.mjs.map +1 -0
- package/dist/chunk-RMUWRESK.cjs +365 -0
- package/dist/chunk-RMUWRESK.cjs.map +1 -0
- package/dist/chunk-ZT35X7KL.mjs +365 -0
- package/dist/chunk-ZT35X7KL.mjs.map +1 -0
- package/dist/codegen.cjs +300 -0
- package/dist/codegen.cjs.map +1 -0
- package/dist/codegen.d.cts +432 -0
- package/dist/codegen.d.ts +432 -0
- package/dist/codegen.mjs +272 -0
- package/dist/codegen.mjs.map +1 -0
- package/dist/constants-DJ_KgZpN.d.cts +449 -0
- package/dist/constants-DJ_KgZpN.d.ts +449 -0
- package/dist/context-Dt6xh_5t.d.cts +30 -0
- package/dist/context-Ml7k_V14.d.ts +30 -0
- package/dist/errors-COsBh7kd.d.cts +88 -0
- package/dist/errors-COsBh7kd.d.ts +88 -0
- package/dist/handler-CZIlZ5vu.d.ts +227 -0
- package/dist/handler-kU9Jf36K.d.cts +227 -0
- package/dist/host.cjs +24 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.cts +24 -0
- package/dist/host.d.ts +24 -0
- package/dist/host.mjs +24 -0
- package/dist/host.mjs.map +1 -0
- package/dist/index.cjs +698 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1016 -0
- package/dist/index.d.ts +1016 -0
- package/dist/index.mjs +698 -0
- package/dist/index.mjs.map +1 -0
- package/dist/manifest.cjs +872 -0
- package/dist/manifest.cjs.map +1 -0
- package/dist/manifest.d.cts +432 -0
- package/dist/manifest.d.ts +432 -0
- package/dist/manifest.mjs +872 -0
- package/dist/manifest.mjs.map +1 -0
- package/dist/matchers-Cz93AK1n.d.cts +74 -0
- package/dist/matchers-Cz93AK1n.d.ts +74 -0
- package/dist/server.cjs +210 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +243 -0
- package/dist/server.d.ts +243 -0
- package/dist/server.mjs +210 -0
- package/dist/server.mjs.map +1 -0
- package/dist/styles.css +367 -0
- package/dist/testing/index.cjs +887 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +512 -0
- package/dist/testing/index.d.ts +512 -0
- package/dist/testing/index.mjs +887 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/testing/jest.cjs +17 -0
- package/dist/testing/jest.cjs.map +1 -0
- package/dist/testing/jest.d.cts +12 -0
- package/dist/testing/jest.d.ts +12 -0
- package/dist/testing/jest.mjs +17 -0
- package/dist/testing/jest.mjs.map +1 -0
- package/dist/testing/vitest.cjs +15 -0
- package/dist/testing/vitest.cjs.map +1 -0
- package/dist/testing/vitest.d.cts +10 -0
- package/dist/testing/vitest.d.ts +10 -0
- package/dist/testing/vitest.mjs +15 -0
- package/dist/testing/vitest.mjs.map +1 -0
- package/dist/types-DDAGLpov.d.ts +715 -0
- package/dist/types-DrpQSv_2.d.cts +715 -0
- package/dist/vite.cjs +1344 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +434 -0
- package/dist/vite.d.ts +434 -0
- package/dist/vite.mjs +1314 -0
- package/dist/vite.mjs.map +1 -0
- package/package.json +268 -0
- package/schema/extension-v2.json +1500 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
type JsonSchema = Record<string, unknown>;
|
|
2
|
+
type ExtensionVisibility = 'public' | 'unlisted' | 'private';
|
|
3
|
+
type ExtensionInstallScope = 'project' | 'organization';
|
|
4
|
+
interface ScopeEntry {
|
|
5
|
+
key: ScopeKey;
|
|
6
|
+
justification?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ProcedureDeclaration {
|
|
9
|
+
input: JsonSchema;
|
|
10
|
+
output: JsonSchema;
|
|
11
|
+
cache?: '1m' | '5m' | '1h';
|
|
12
|
+
kind?: 'read' | 'write';
|
|
13
|
+
}
|
|
14
|
+
interface StorageCollection {
|
|
15
|
+
scope: 'user' | 'install' | 'organization';
|
|
16
|
+
singleton?: boolean;
|
|
17
|
+
schema: JsonSchema;
|
|
18
|
+
}
|
|
19
|
+
interface PageContribution {
|
|
20
|
+
id: string;
|
|
21
|
+
title: string;
|
|
22
|
+
entry: string;
|
|
23
|
+
nav?: boolean;
|
|
24
|
+
mobile?: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface TabContribution {
|
|
27
|
+
id: string;
|
|
28
|
+
title: string;
|
|
29
|
+
entry: string;
|
|
30
|
+
page: HostPage;
|
|
31
|
+
mobile?: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface WidgetContribution {
|
|
34
|
+
id: string;
|
|
35
|
+
title: string;
|
|
36
|
+
entry: string;
|
|
37
|
+
page: HostPage;
|
|
38
|
+
slot: SlotId;
|
|
39
|
+
size: '1x1' | '2x1' | '2x2';
|
|
40
|
+
expandable?: boolean;
|
|
41
|
+
}
|
|
42
|
+
interface SeriesContribution {
|
|
43
|
+
id: string;
|
|
44
|
+
label: string;
|
|
45
|
+
chart: HostChart;
|
|
46
|
+
metric: string;
|
|
47
|
+
}
|
|
48
|
+
interface BannerContribution {
|
|
49
|
+
id: string;
|
|
50
|
+
page: HostPage;
|
|
51
|
+
event: string;
|
|
52
|
+
}
|
|
53
|
+
interface RowActionContribution {
|
|
54
|
+
id: string;
|
|
55
|
+
title: string;
|
|
56
|
+
table: HostTable;
|
|
57
|
+
entry: string;
|
|
58
|
+
}
|
|
59
|
+
interface MarkerContribution {
|
|
60
|
+
id: string;
|
|
61
|
+
label: string;
|
|
62
|
+
chart: HostChart | '*';
|
|
63
|
+
event: string;
|
|
64
|
+
glyph: string;
|
|
65
|
+
}
|
|
66
|
+
interface SettingsContribution {
|
|
67
|
+
entry: string;
|
|
68
|
+
schema: JsonSchema;
|
|
69
|
+
}
|
|
70
|
+
interface CredentialField {
|
|
71
|
+
name: string;
|
|
72
|
+
label: string;
|
|
73
|
+
type: 'text' | 'password' | 'textarea' | 'file' | 'select';
|
|
74
|
+
required: boolean;
|
|
75
|
+
options?: string[];
|
|
76
|
+
help?: string;
|
|
77
|
+
}
|
|
78
|
+
interface ConnectorAuth {
|
|
79
|
+
method: 'none' | 'api_key' | 'oauth';
|
|
80
|
+
fields?: CredentialField[];
|
|
81
|
+
oauth?: {
|
|
82
|
+
authorizationUrl: string;
|
|
83
|
+
tokenUrl: string;
|
|
84
|
+
scopes: string[];
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
interface DimensionDeclaration {
|
|
88
|
+
key: string;
|
|
89
|
+
label: string;
|
|
90
|
+
}
|
|
91
|
+
interface MetricDeclaration {
|
|
92
|
+
key: string;
|
|
93
|
+
label: string;
|
|
94
|
+
unit: 'count' | 'ratio' | 'currency' | 'seconds' | 'bytes';
|
|
95
|
+
kind: 'gauge' | 'counter';
|
|
96
|
+
dimensions?: DimensionDeclaration[];
|
|
97
|
+
backfillDays?: number;
|
|
98
|
+
}
|
|
99
|
+
interface ConnectorContribution {
|
|
100
|
+
auth?: ConnectorAuth;
|
|
101
|
+
sync?: '5m' | '15m' | '1h' | '6h' | '24h';
|
|
102
|
+
metrics?: MetricDeclaration[];
|
|
103
|
+
}
|
|
104
|
+
interface WebhookContribution {
|
|
105
|
+
event: string;
|
|
106
|
+
as: 'alert' | 'banner' | 'event';
|
|
107
|
+
payload: JsonSchema;
|
|
108
|
+
}
|
|
109
|
+
interface ToolDeclaration {
|
|
110
|
+
id: string;
|
|
111
|
+
description: string;
|
|
112
|
+
input: JsonSchema;
|
|
113
|
+
returns: 'comparison' | 'table' | 'series' | 'list' | 'value';
|
|
114
|
+
cost: 'low' | 'medium' | 'high';
|
|
115
|
+
cache?: '1m' | '5m' | '1h';
|
|
116
|
+
}
|
|
117
|
+
interface MentionDeclaration {
|
|
118
|
+
id: string;
|
|
119
|
+
label: string;
|
|
120
|
+
list: string;
|
|
121
|
+
}
|
|
122
|
+
interface ActionDeclaration {
|
|
123
|
+
id: string;
|
|
124
|
+
description: string;
|
|
125
|
+
input: JsonSchema;
|
|
126
|
+
approval: true;
|
|
127
|
+
reversible: boolean;
|
|
128
|
+
scope: ScopeKey;
|
|
129
|
+
estimatesCost?: boolean;
|
|
130
|
+
}
|
|
131
|
+
interface KnowledgeDeclaration {
|
|
132
|
+
id: string;
|
|
133
|
+
category: 'metric_definitions' | 'gotchas' | 'setup';
|
|
134
|
+
file: string;
|
|
135
|
+
}
|
|
136
|
+
interface SkillDeclaration {
|
|
137
|
+
id: string;
|
|
138
|
+
name: string;
|
|
139
|
+
description: string;
|
|
140
|
+
file: string;
|
|
141
|
+
tools?: string[];
|
|
142
|
+
}
|
|
143
|
+
interface PromptDeclaration {
|
|
144
|
+
id: string;
|
|
145
|
+
title: string;
|
|
146
|
+
template: string;
|
|
147
|
+
surfaces: ('chat_suggestion' | 'widget' | 'page' | 'result_card')[];
|
|
148
|
+
after?: string[];
|
|
149
|
+
input?: JsonSchema;
|
|
150
|
+
}
|
|
151
|
+
interface ContextDeclaration {
|
|
152
|
+
id: string;
|
|
153
|
+
description: string;
|
|
154
|
+
when: ('turn_start' | 'mention')[];
|
|
155
|
+
cache?: '1m' | '5m' | '1h';
|
|
156
|
+
}
|
|
157
|
+
interface AiContribution {
|
|
158
|
+
tools?: ToolDeclaration[];
|
|
159
|
+
mentions?: MentionDeclaration[];
|
|
160
|
+
actions?: ActionDeclaration[];
|
|
161
|
+
knowledge?: KnowledgeDeclaration[];
|
|
162
|
+
skills?: SkillDeclaration[];
|
|
163
|
+
prompts?: PromptDeclaration[];
|
|
164
|
+
context?: ContextDeclaration[];
|
|
165
|
+
}
|
|
166
|
+
interface WorkContribution {
|
|
167
|
+
kind: 'tracker' | 'docs' | 'chat';
|
|
168
|
+
container: {
|
|
169
|
+
label: string;
|
|
170
|
+
list: string;
|
|
171
|
+
};
|
|
172
|
+
creates: ('issue' | 'page' | 'message')[];
|
|
173
|
+
fields: {
|
|
174
|
+
priority?: string[];
|
|
175
|
+
labels?: boolean;
|
|
176
|
+
assignee?: boolean;
|
|
177
|
+
required: string[];
|
|
178
|
+
};
|
|
179
|
+
attachments: ('image' | 'link')[];
|
|
180
|
+
comments: 'two-way' | 'none';
|
|
181
|
+
status?: {
|
|
182
|
+
webhook: string;
|
|
183
|
+
map: Record<'open' | 'in_progress' | 'done', string[]>;
|
|
184
|
+
};
|
|
185
|
+
identity: 'user' | 'install';
|
|
186
|
+
}
|
|
187
|
+
interface ExtensionListing {
|
|
188
|
+
longDescription?: string;
|
|
189
|
+
screenshots?: string[];
|
|
190
|
+
website?: string;
|
|
191
|
+
supportUrl?: string;
|
|
192
|
+
privacyUrl?: string;
|
|
193
|
+
}
|
|
194
|
+
interface ExtensionManifest {
|
|
195
|
+
$schema?: string;
|
|
196
|
+
id: string;
|
|
197
|
+
name: string;
|
|
198
|
+
description: string;
|
|
199
|
+
icon: string;
|
|
200
|
+
category: ExtensionCategory;
|
|
201
|
+
sdk: string;
|
|
202
|
+
visibility: ExtensionVisibility;
|
|
203
|
+
installScope: ExtensionInstallScope;
|
|
204
|
+
scopes: ScopeEntry[];
|
|
205
|
+
contributes: {
|
|
206
|
+
pages?: PageContribution[];
|
|
207
|
+
tabs?: TabContribution[];
|
|
208
|
+
widgets?: WidgetContribution[];
|
|
209
|
+
series?: SeriesContribution[];
|
|
210
|
+
banners?: BannerContribution[];
|
|
211
|
+
rowActions?: RowActionContribution[];
|
|
212
|
+
markers?: MarkerContribution[];
|
|
213
|
+
settings?: SettingsContribution;
|
|
214
|
+
storage?: Record<string, StorageCollection>;
|
|
215
|
+
connector?: ConnectorContribution;
|
|
216
|
+
webhooks?: WebhookContribution[];
|
|
217
|
+
ai?: AiContribution;
|
|
218
|
+
work?: WorkContribution;
|
|
219
|
+
};
|
|
220
|
+
server?: {
|
|
221
|
+
baseUrl: string;
|
|
222
|
+
sandboxBaseUrl?: string;
|
|
223
|
+
procedures?: Record<string, ProcedureDeclaration>;
|
|
224
|
+
events?: HostEventName[];
|
|
225
|
+
};
|
|
226
|
+
telemetry?: string[];
|
|
227
|
+
listing?: ExtensionListing;
|
|
228
|
+
pricing?: never;
|
|
229
|
+
score?: never;
|
|
230
|
+
}
|
|
231
|
+
type ExposableKind = 'page' | 'tab' | 'widget' | 'rowAction' | 'settings';
|
|
232
|
+
interface UiContributionRef {
|
|
233
|
+
kind: ExposableKind;
|
|
234
|
+
id: string;
|
|
235
|
+
entry: string;
|
|
236
|
+
expose: string;
|
|
237
|
+
}
|
|
238
|
+
interface ManifestIssue {
|
|
239
|
+
path: string;
|
|
240
|
+
message: string;
|
|
241
|
+
}
|
|
242
|
+
type ManifestValidation = {
|
|
243
|
+
ok: true;
|
|
244
|
+
manifest: ExtensionManifest;
|
|
245
|
+
} | {
|
|
246
|
+
ok: false;
|
|
247
|
+
issues: ManifestIssue[];
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
declare const SCOPES: readonly [{
|
|
251
|
+
readonly key: "ui:render";
|
|
252
|
+
readonly label: "Render UI";
|
|
253
|
+
readonly description: "Render the declared pages, tabs, widgets, row actions and settings panel, and open chat with a visible prompt";
|
|
254
|
+
readonly requiresSecurityReview: false;
|
|
255
|
+
readonly requiresJustification: false;
|
|
256
|
+
}, {
|
|
257
|
+
readonly key: "projects:read";
|
|
258
|
+
readonly label: "Read the project";
|
|
259
|
+
readonly description: "Project name, platforms and store identity";
|
|
260
|
+
readonly requiresSecurityReview: false;
|
|
261
|
+
readonly requiresJustification: false;
|
|
262
|
+
}, {
|
|
263
|
+
readonly key: "analytics:read";
|
|
264
|
+
readonly label: "Read analytics";
|
|
265
|
+
readonly description: "Downloads, impressions, page views and conversion series";
|
|
266
|
+
readonly requiresSecurityReview: false;
|
|
267
|
+
readonly requiresJustification: false;
|
|
268
|
+
}, {
|
|
269
|
+
readonly key: "store.metadata:read";
|
|
270
|
+
readonly label: "Read store metadata";
|
|
271
|
+
readonly description: "Listing metadata, keyword set and keyword positions";
|
|
272
|
+
readonly requiresSecurityReview: false;
|
|
273
|
+
readonly requiresJustification: false;
|
|
274
|
+
}, {
|
|
275
|
+
readonly key: "reviews:read";
|
|
276
|
+
readonly label: "Read store reviews";
|
|
277
|
+
readonly description: "Review text, ratings and replies";
|
|
278
|
+
readonly requiresSecurityReview: false;
|
|
279
|
+
readonly requiresJustification: false;
|
|
280
|
+
}, {
|
|
281
|
+
readonly key: "crashes:read";
|
|
282
|
+
readonly label: "Read crash data";
|
|
283
|
+
readonly description: "Crash-free rate and issue counts";
|
|
284
|
+
readonly requiresSecurityReview: false;
|
|
285
|
+
readonly requiresJustification: false;
|
|
286
|
+
}, {
|
|
287
|
+
readonly key: "revenue:read";
|
|
288
|
+
readonly label: "Read revenue";
|
|
289
|
+
readonly description: "MRR, revenue series and refund counts";
|
|
290
|
+
readonly requiresSecurityReview: false;
|
|
291
|
+
readonly requiresJustification: true;
|
|
292
|
+
}, {
|
|
293
|
+
readonly key: "metrics:write";
|
|
294
|
+
readonly label: "Write connector metrics";
|
|
295
|
+
readonly description: "Write the metrics this extension declares into the metrics store";
|
|
296
|
+
readonly requiresSecurityReview: false;
|
|
297
|
+
readonly requiresJustification: false;
|
|
298
|
+
}, {
|
|
299
|
+
readonly key: "alerts:write";
|
|
300
|
+
readonly label: "Raise alerts and banners";
|
|
301
|
+
readonly description: "Turn declared webhooks into alerts and banners, at most three a day per project";
|
|
302
|
+
readonly requiresSecurityReview: false;
|
|
303
|
+
readonly requiresJustification: true;
|
|
304
|
+
}, {
|
|
305
|
+
readonly key: "insights:write";
|
|
306
|
+
readonly label: "Post insights";
|
|
307
|
+
readonly description: "Post insights to Home and to chat";
|
|
308
|
+
readonly requiresSecurityReview: false;
|
|
309
|
+
readonly requiresJustification: true;
|
|
310
|
+
}, {
|
|
311
|
+
readonly key: "ai:tools";
|
|
312
|
+
readonly label: "Add assistant tools";
|
|
313
|
+
readonly description: "Offer tools and mentions to the assistant";
|
|
314
|
+
readonly requiresSecurityReview: false;
|
|
315
|
+
readonly requiresJustification: false;
|
|
316
|
+
}, {
|
|
317
|
+
readonly key: "ai:actions";
|
|
318
|
+
readonly label: "Run assistant actions";
|
|
319
|
+
readonly description: "Run declared actions, each behind the approval card";
|
|
320
|
+
readonly requiresSecurityReview: true;
|
|
321
|
+
readonly requiresJustification: true;
|
|
322
|
+
}, {
|
|
323
|
+
readonly key: "store.metadata:write";
|
|
324
|
+
readonly label: "Propose store metadata changes";
|
|
325
|
+
readonly description: "Propose listing changes through a Tappify approval";
|
|
326
|
+
readonly requiresSecurityReview: true;
|
|
327
|
+
readonly requiresJustification: true;
|
|
328
|
+
}, {
|
|
329
|
+
readonly key: "autopilot:trigger";
|
|
330
|
+
readonly label: "Trigger automated store actions";
|
|
331
|
+
readonly description: "Start automated store actions on the owner’s behalf";
|
|
332
|
+
readonly requiresSecurityReview: true;
|
|
333
|
+
readonly requiresJustification: true;
|
|
334
|
+
}, {
|
|
335
|
+
readonly key: "work:create";
|
|
336
|
+
readonly label: "Create work items";
|
|
337
|
+
readonly description: "Create issues, pages or messages in the vendor’s system";
|
|
338
|
+
readonly requiresSecurityReview: false;
|
|
339
|
+
readonly requiresJustification: true;
|
|
340
|
+
}, {
|
|
341
|
+
readonly key: "work:sync";
|
|
342
|
+
readonly label: "Sync work items";
|
|
343
|
+
readonly description: "Two-way comments and status on created work items";
|
|
344
|
+
readonly requiresSecurityReview: false;
|
|
345
|
+
readonly requiresJustification: true;
|
|
346
|
+
}, {
|
|
347
|
+
readonly key: "storage:write";
|
|
348
|
+
readonly label: "Use hosted storage";
|
|
349
|
+
readonly description: "Read and write this extension’s own hosted storage collections";
|
|
350
|
+
readonly requiresSecurityReview: false;
|
|
351
|
+
readonly requiresJustification: false;
|
|
352
|
+
}, {
|
|
353
|
+
readonly key: "messaging:send";
|
|
354
|
+
readonly label: "Send messages to end users";
|
|
355
|
+
readonly description: "Send messages or push notifications to the owner’s end users through owner-supplied credentials";
|
|
356
|
+
readonly requiresSecurityReview: true;
|
|
357
|
+
readonly requiresJustification: true;
|
|
358
|
+
}, {
|
|
359
|
+
readonly key: "ai:skills";
|
|
360
|
+
readonly label: "Shape the assistant";
|
|
361
|
+
readonly description: "Add skills, prompt templates and context providers that shape the assistant’s behaviour";
|
|
362
|
+
readonly requiresSecurityReview: false;
|
|
363
|
+
readonly requiresJustification: true;
|
|
364
|
+
}];
|
|
365
|
+
type ScopeDefinition = (typeof SCOPES)[number];
|
|
366
|
+
/** Every scope an extension can ask for under `scopes` in its manifest. */
|
|
367
|
+
type ScopeKey = ScopeDefinition['key'];
|
|
368
|
+
declare const SCOPE_KEYS: readonly ScopeKey[];
|
|
369
|
+
declare const SLOTS: readonly ["kpi-row", "insights", "sidebar", "below-chart", "below-list"];
|
|
370
|
+
/** The anchors on a host page a widget can be declared at. */
|
|
371
|
+
type SlotId = (typeof SLOTS)[number];
|
|
372
|
+
declare const CHARTS: readonly ["installs-activity", "conversion", "release-cadence"];
|
|
373
|
+
type HostChart = (typeof CHARTS)[number];
|
|
374
|
+
declare const PAGES: readonly [{
|
|
375
|
+
readonly key: "overview";
|
|
376
|
+
readonly label: "Home";
|
|
377
|
+
readonly route: "/projects/:id/overview";
|
|
378
|
+
readonly slots: readonly ["kpi-row", "insights", "sidebar"];
|
|
379
|
+
readonly charts: readonly ["installs-activity"];
|
|
380
|
+
readonly tabs: true;
|
|
381
|
+
readonly banners: true;
|
|
382
|
+
}, {
|
|
383
|
+
readonly key: "analytics";
|
|
384
|
+
readonly label: "Analytics";
|
|
385
|
+
readonly route: "/projects/:id/analytics";
|
|
386
|
+
readonly slots: readonly ["kpi-row", "below-chart", "sidebar"];
|
|
387
|
+
readonly charts: readonly ["installs-activity", "conversion"];
|
|
388
|
+
readonly tabs: true;
|
|
389
|
+
readonly banners: true;
|
|
390
|
+
}, {
|
|
391
|
+
readonly key: "deployments";
|
|
392
|
+
readonly label: "Deployments";
|
|
393
|
+
readonly route: "/projects/:id/deployments";
|
|
394
|
+
readonly slots: readonly ["sidebar", "below-list"];
|
|
395
|
+
readonly charts: readonly ["release-cadence"];
|
|
396
|
+
readonly tabs: true;
|
|
397
|
+
readonly banners: false;
|
|
398
|
+
}, {
|
|
399
|
+
readonly key: "ai_chat";
|
|
400
|
+
readonly label: "Assistant";
|
|
401
|
+
readonly route: "chat";
|
|
402
|
+
readonly slots: readonly [];
|
|
403
|
+
readonly charts: readonly [];
|
|
404
|
+
readonly tabs: false;
|
|
405
|
+
readonly banners: false;
|
|
406
|
+
}];
|
|
407
|
+
type PageDefinition = (typeof PAGES)[number];
|
|
408
|
+
/** The host pages a contribution can attach a tab, widget or banner to. */
|
|
409
|
+
type HostPage = PageDefinition['key'];
|
|
410
|
+
declare const PAGE_KEYS: readonly HostPage[];
|
|
411
|
+
declare const TABLES: readonly [{
|
|
412
|
+
readonly key: "analytics.keywords";
|
|
413
|
+
readonly label: "Keywords";
|
|
414
|
+
}, {
|
|
415
|
+
readonly key: "analytics.reviews";
|
|
416
|
+
readonly label: "Reviews";
|
|
417
|
+
}, {
|
|
418
|
+
readonly key: "deployments.releases";
|
|
419
|
+
readonly label: "Releases";
|
|
420
|
+
}, {
|
|
421
|
+
readonly key: "deployments.builds";
|
|
422
|
+
readonly label: "Builds";
|
|
423
|
+
}];
|
|
424
|
+
type TableDefinition = (typeof TABLES)[number];
|
|
425
|
+
type HostTable = TableDefinition['key'];
|
|
426
|
+
declare const TABLE_KEYS: readonly HostTable[];
|
|
427
|
+
declare const KINDS: readonly ["page", "tab", "widget", "series", "banner", "rowAction", "marker", "settings", "storage", "connector", "webhook", "tool", "mention", "action", "knowledge", "skill", "prompt", "context", "work"];
|
|
428
|
+
type ContributionKind = (typeof KINDS)[number];
|
|
429
|
+
declare const CATEGORIES: readonly ["market_data", "subscriptions", "product_analytics", "crashes", "attribution", "experiments", "messaging", "session_replay", "localization", "design", "ci_cd", "trackers", "support", "chat", "ad_monetization", "warehouse", "compliance", "additional_stores"];
|
|
430
|
+
type ExtensionCategory = (typeof CATEGORIES)[number];
|
|
431
|
+
declare const EVENTS: readonly ["release.shipped", "metadata.changed", "keyword.set_changed", "screenshots.updated", "price.changed", "featuring.started", "score.changed", "incident.opened", "incident.resolved", "playbook.step_approved", "review.thread_opened", "review.thread_resolved", "approval.requested", "digest.sent", "install.created", "install.paused", "install.resumed", "install.revoked", "install.token_rotated", "scopes.changed", "settings.changed"];
|
|
432
|
+
/** Every event Tappify emits, which a mount or a server can subscribe to. */
|
|
433
|
+
type HostEventName = (typeof EVENTS)[number];
|
|
434
|
+
declare const SERVED_SDK_MAJORS: readonly number[];
|
|
435
|
+
/** The `kind` of every read `tap.data.query` accepts, one per scope it needs. */
|
|
436
|
+
type DataQueryKind = 'project' | 'series' | 'keywords' | 'listing' | 'reviews' | 'crashes' | 'revenue';
|
|
437
|
+
declare const QUERY_SCOPES: Record<DataQueryKind, ScopeKey>;
|
|
438
|
+
/**
|
|
439
|
+
* The keys a tool's answer carries for each `returns` kind it may declare.
|
|
440
|
+
* `validateToolResponse`, `tappify extension doctor` and the host all read
|
|
441
|
+
* this one table, so a wrong body fails the same way wherever it is checked.
|
|
442
|
+
*/
|
|
443
|
+
declare const CARD_KEYS: Record<ToolDeclaration['returns'], string[]>;
|
|
444
|
+
declare const findScope: (key: string) => ScopeDefinition | undefined;
|
|
445
|
+
declare const findPage: (key: string) => PageDefinition | undefined;
|
|
446
|
+
declare const findTable: (key: string) => TableDefinition | undefined;
|
|
447
|
+
declare const slotsForPage: (page: string) => readonly SlotId[];
|
|
448
|
+
|
|
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 };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Context } from 'react';
|
|
2
|
+
import { T as Tap } from './types-DrpQSv_2.cjs';
|
|
3
|
+
|
|
4
|
+
declare const TapContext: Context<Tap | null>;
|
|
5
|
+
/**
|
|
6
|
+
* Returns the whole bridge the host mounted this component with.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Throws `TapError` with code `TAP_OUTSIDE_HOST` when no Tappify mount is above
|
|
10
|
+
* the component. The object it returns does not re-render the component when the
|
|
11
|
+
* host changes a member; read through `useTapFilters`, `useTapTheme` and the
|
|
12
|
+
* other slice hooks where that matters.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { TapButton, useTap } from '@tappify/extension-sdk';
|
|
17
|
+
*
|
|
18
|
+
* function CopyId() {
|
|
19
|
+
* const tap = useTap();
|
|
20
|
+
* return (
|
|
21
|
+
* <TapButton onClick={() => void tap.ui.copy(tap.project.id)}>
|
|
22
|
+
* Copy project id
|
|
23
|
+
* </TapButton>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function useTap(): Tap;
|
|
29
|
+
|
|
30
|
+
export { TapContext as T, useTap as u };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Context } from 'react';
|
|
2
|
+
import { T as Tap } from './types-DDAGLpov.js';
|
|
3
|
+
|
|
4
|
+
declare const TapContext: Context<Tap | null>;
|
|
5
|
+
/**
|
|
6
|
+
* Returns the whole bridge the host mounted this component with.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Throws `TapError` with code `TAP_OUTSIDE_HOST` when no Tappify mount is above
|
|
10
|
+
* the component. The object it returns does not re-render the component when the
|
|
11
|
+
* host changes a member; read through `useTapFilters`, `useTapTheme` and the
|
|
12
|
+
* other slice hooks where that matters.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { TapButton, useTap } from '@tappify/extension-sdk';
|
|
17
|
+
*
|
|
18
|
+
* function CopyId() {
|
|
19
|
+
* const tap = useTap();
|
|
20
|
+
* return (
|
|
21
|
+
* <TapButton onClick={() => void tap.ui.copy(tap.project.id)}>
|
|
22
|
+
* Copy project id
|
|
23
|
+
* </TapButton>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function useTap(): Tap;
|
|
29
|
+
|
|
30
|
+
export { TapContext as T, useTap as u };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Every code a `TapError` the SDK raises carries. */
|
|
2
|
+
type TapErrorCode = 'TAP_OUTSIDE_HOST' | 'TAP_SCOPE_MISSING' | 'TAP_UNKNOWN_COLLECTION' | 'TAP_UNKNOWN_PROCEDURE' | 'TAP_NO_PORTAL' | 'TAP_NO_QUERY_CLIENT' | 'TAP_MANIFEST_INVALID' | 'TAP_ENTRY_MISSING' | 'TAP_STYLES_UNRESOLVED' | 'TAP_SCHEMA_UNRESOLVED' | 'TAP_TOKEN_MISSING' | 'TAP_TOKEN_INVALID' | 'TAP_TOKEN_AUDIENCE' | 'TAP_EVENT_ID_MISSING' | 'TAP_BODY_INVALID' | 'TAP_BODY_TOO_LARGE' | 'TAP_ROUTE_UNKNOWN' | 'TAP_HANDLER_MISSING' | 'TAP_INTERNAL_ERROR' | 'TAP_WEBHOOK_REJECTED' | 'TAP_TEST_TARGET_INVALID';
|
|
3
|
+
/**
|
|
4
|
+
* The same codes as `TapErrorCode`, as an array to iterate or check membership
|
|
5
|
+
* against at runtime.
|
|
6
|
+
*/
|
|
7
|
+
declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
8
|
+
/**
|
|
9
|
+
* The error the SDK and the host raise when a call cannot be served at all.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* The SDK throws it for a mount outside the host (`TAP_OUTSIDE_HOST`), a
|
|
13
|
+
* collection or procedure the manifest does not declare
|
|
14
|
+
* (`TAP_UNKNOWN_COLLECTION`, `TAP_UNKNOWN_PROCEDURE`), a missing portal or query
|
|
15
|
+
* client, a token the server rejected, and a misused testing helper. The host
|
|
16
|
+
* turns a refused read or write into `TAP_SCOPE_MISSING`. Branch on `code`, which
|
|
17
|
+
* is stable; the message is prose and changes. An error your own server raised is
|
|
18
|
+
* a `TapServerError` instead.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import { TapError, TapErrorState, useTapQuery } from '@tappify/extension-sdk';
|
|
23
|
+
*
|
|
24
|
+
* function Revenue() {
|
|
25
|
+
* const revenue = useTapQuery({
|
|
26
|
+
* kind: 'revenue',
|
|
27
|
+
* range: { from: '2026-09-01', to: '2026-09-08' },
|
|
28
|
+
* });
|
|
29
|
+
* if (TapError.is(revenue.error) && revenue.error.code === 'TAP_SCOPE_MISSING') {
|
|
30
|
+
* return <TapErrorState title="Revenue is not shared with this extension" />;
|
|
31
|
+
* }
|
|
32
|
+
* return <span>{revenue.data?.mrr ?? 0}</span>;
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare class TapError extends Error {
|
|
37
|
+
readonly code: TapErrorCode;
|
|
38
|
+
constructor(code: TapErrorCode, message: string);
|
|
39
|
+
/**
|
|
40
|
+
* Narrows an unknown value to a `TapError`, by name and by a code it
|
|
41
|
+
* recognises, so it holds across module instances.
|
|
42
|
+
*/
|
|
43
|
+
static is(value: unknown): value is TapError;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The error a vendor server throws to answer a Tappify call with a code and a
|
|
47
|
+
* message the owner sees.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* `createTappifyHandler` catches it and answers `{ error: { code, message } }`
|
|
51
|
+
* with `status`, or 400 when no status was given; the host relays both to the
|
|
52
|
+
* calling mount, where they arrive as the `error` of `useTapServer`. Pick a code
|
|
53
|
+
* of your own and keep it stable — the SDK's own codes are `SERVER_ERROR_CODES` —
|
|
54
|
+
* and write the message for the owner, who reads it on screen.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { TapServerError } from '@tappify/extension-sdk/server';
|
|
59
|
+
*
|
|
60
|
+
* function assertRange(days: number) {
|
|
61
|
+
* if (days > 0) return;
|
|
62
|
+
* throw new TapServerError(
|
|
63
|
+
* 'RANGE_TOO_SHORT',
|
|
64
|
+
* 'getSummary needs a range of at least one day. Widen the date picker, then retry.',
|
|
65
|
+
* 400,
|
|
66
|
+
* );
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare class TapServerError extends Error {
|
|
71
|
+
readonly code: string;
|
|
72
|
+
readonly status: number | undefined;
|
|
73
|
+
constructor(code: string, message: string, status?: number);
|
|
74
|
+
/** The wire body the handler answers with, without the status. */
|
|
75
|
+
toJSON(): {
|
|
76
|
+
error: {
|
|
77
|
+
code: string;
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Narrows an unknown value to a `TapServerError` by name and by carrying a
|
|
83
|
+
* string `code`, so it holds across module instances.
|
|
84
|
+
*/
|
|
85
|
+
static is(value: unknown): value is TapServerError;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { TAP_ERROR_CODES as T, TapError as a, type TapErrorCode as b, TapServerError as c };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Every code a `TapError` the SDK raises carries. */
|
|
2
|
+
type TapErrorCode = 'TAP_OUTSIDE_HOST' | 'TAP_SCOPE_MISSING' | 'TAP_UNKNOWN_COLLECTION' | 'TAP_UNKNOWN_PROCEDURE' | 'TAP_NO_PORTAL' | 'TAP_NO_QUERY_CLIENT' | 'TAP_MANIFEST_INVALID' | 'TAP_ENTRY_MISSING' | 'TAP_STYLES_UNRESOLVED' | 'TAP_SCHEMA_UNRESOLVED' | 'TAP_TOKEN_MISSING' | 'TAP_TOKEN_INVALID' | 'TAP_TOKEN_AUDIENCE' | 'TAP_EVENT_ID_MISSING' | 'TAP_BODY_INVALID' | 'TAP_BODY_TOO_LARGE' | 'TAP_ROUTE_UNKNOWN' | 'TAP_HANDLER_MISSING' | 'TAP_INTERNAL_ERROR' | 'TAP_WEBHOOK_REJECTED' | 'TAP_TEST_TARGET_INVALID';
|
|
3
|
+
/**
|
|
4
|
+
* The same codes as `TapErrorCode`, as an array to iterate or check membership
|
|
5
|
+
* against at runtime.
|
|
6
|
+
*/
|
|
7
|
+
declare const TAP_ERROR_CODES: readonly TapErrorCode[];
|
|
8
|
+
/**
|
|
9
|
+
* The error the SDK and the host raise when a call cannot be served at all.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* The SDK throws it for a mount outside the host (`TAP_OUTSIDE_HOST`), a
|
|
13
|
+
* collection or procedure the manifest does not declare
|
|
14
|
+
* (`TAP_UNKNOWN_COLLECTION`, `TAP_UNKNOWN_PROCEDURE`), a missing portal or query
|
|
15
|
+
* client, a token the server rejected, and a misused testing helper. The host
|
|
16
|
+
* turns a refused read or write into `TAP_SCOPE_MISSING`. Branch on `code`, which
|
|
17
|
+
* is stable; the message is prose and changes. An error your own server raised is
|
|
18
|
+
* a `TapServerError` instead.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import { TapError, TapErrorState, useTapQuery } from '@tappify/extension-sdk';
|
|
23
|
+
*
|
|
24
|
+
* function Revenue() {
|
|
25
|
+
* const revenue = useTapQuery({
|
|
26
|
+
* kind: 'revenue',
|
|
27
|
+
* range: { from: '2026-09-01', to: '2026-09-08' },
|
|
28
|
+
* });
|
|
29
|
+
* if (TapError.is(revenue.error) && revenue.error.code === 'TAP_SCOPE_MISSING') {
|
|
30
|
+
* return <TapErrorState title="Revenue is not shared with this extension" />;
|
|
31
|
+
* }
|
|
32
|
+
* return <span>{revenue.data?.mrr ?? 0}</span>;
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare class TapError extends Error {
|
|
37
|
+
readonly code: TapErrorCode;
|
|
38
|
+
constructor(code: TapErrorCode, message: string);
|
|
39
|
+
/**
|
|
40
|
+
* Narrows an unknown value to a `TapError`, by name and by a code it
|
|
41
|
+
* recognises, so it holds across module instances.
|
|
42
|
+
*/
|
|
43
|
+
static is(value: unknown): value is TapError;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The error a vendor server throws to answer a Tappify call with a code and a
|
|
47
|
+
* message the owner sees.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* `createTappifyHandler` catches it and answers `{ error: { code, message } }`
|
|
51
|
+
* with `status`, or 400 when no status was given; the host relays both to the
|
|
52
|
+
* calling mount, where they arrive as the `error` of `useTapServer`. Pick a code
|
|
53
|
+
* of your own and keep it stable — the SDK's own codes are `SERVER_ERROR_CODES` —
|
|
54
|
+
* and write the message for the owner, who reads it on screen.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { TapServerError } from '@tappify/extension-sdk/server';
|
|
59
|
+
*
|
|
60
|
+
* function assertRange(days: number) {
|
|
61
|
+
* if (days > 0) return;
|
|
62
|
+
* throw new TapServerError(
|
|
63
|
+
* 'RANGE_TOO_SHORT',
|
|
64
|
+
* 'getSummary needs a range of at least one day. Widen the date picker, then retry.',
|
|
65
|
+
* 400,
|
|
66
|
+
* );
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare class TapServerError extends Error {
|
|
71
|
+
readonly code: string;
|
|
72
|
+
readonly status: number | undefined;
|
|
73
|
+
constructor(code: string, message: string, status?: number);
|
|
74
|
+
/** The wire body the handler answers with, without the status. */
|
|
75
|
+
toJSON(): {
|
|
76
|
+
error: {
|
|
77
|
+
code: string;
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Narrows an unknown value to a `TapServerError` by name and by carrying a
|
|
83
|
+
* string `code`, so it holds across module instances.
|
|
84
|
+
*/
|
|
85
|
+
static is(value: unknown): value is TapServerError;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { TAP_ERROR_CODES as T, TapError as a, type TapErrorCode as b, TapServerError as c };
|