@tanqory/plugin-sdk 0.4.0 → 0.6.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/dist/manifest.d.ts +24 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +57 -2
- package/dist/manifest.js.map +1 -1
- package/dist/manifest.schema.spec.d.ts +18 -0
- package/dist/manifest.schema.spec.d.ts.map +1 -0
- package/dist/manifest.schema.spec.js +164 -0
- package/dist/manifest.schema.spec.js.map +1 -0
- package/dist/manifest.spec.js +60 -0
- package/dist/manifest.spec.js.map +1 -1
- package/package.json +5 -2
- package/schema/tanqory-app.schema.json +167 -0
package/dist/manifest.d.ts
CHANGED
|
@@ -55,12 +55,32 @@ export interface TanqoryAppManifest {
|
|
|
55
55
|
width?: 'full' | 'centered';
|
|
56
56
|
};
|
|
57
57
|
/**
|
|
58
|
-
* Platform capabilities the app REQUESTS
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
58
|
+
* Platform capabilities the app REQUESTS. A request is not a grant: review
|
|
59
|
+
* must approve each one onto the app before it has any effect — declaring it
|
|
60
|
+
* here is how you ask.
|
|
61
|
+
*
|
|
62
|
+
* Two forms:
|
|
63
|
+
* - a bare slug from Tanqory's closed vocabulary, e.g. `marketing-suite`
|
|
64
|
+
* - a namespaced notification capability, `<family>:<name>`:
|
|
65
|
+
* - `notification-override:<typeName>` — send this notification type
|
|
66
|
+
* *instead of* the platform (e.g. `notification-override:order_new`)
|
|
67
|
+
* - `notification-channel:<channelName>` — add a delivery channel
|
|
68
|
+
* alongside the platform's own (e.g. `notification-channel:line`)
|
|
69
|
+
*
|
|
70
|
+
* The family prefixes are checked here; the type and channel names are not.
|
|
71
|
+
* That vocabulary is the platform's registry, it grows without an SDK
|
|
72
|
+
* release, and a copy of it in this package would be stale the week after
|
|
73
|
+
* it shipped — same reason `navigation.placement` is shape-checked only.
|
|
62
74
|
*/
|
|
63
75
|
provides?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Where the platform POSTs a rendered message for the notification types and
|
|
78
|
+
* channels you took over. Required as soon as `provides` names one — a
|
|
79
|
+
* takeover with nowhere to deliver silently drops every message it claimed.
|
|
80
|
+
*/
|
|
81
|
+
notifications?: {
|
|
82
|
+
dispatchUrl: string;
|
|
83
|
+
};
|
|
64
84
|
}
|
|
65
85
|
export declare class ManifestError extends Error {
|
|
66
86
|
readonly problems: string[];
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9C,qFAAqF;IACrF,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAQzB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAC9B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAA;IAClF,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;IAC5D
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9C,qFAAqF;IACrF,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAQzB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAC9B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAA;IAClF,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;IAC5D;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CACxC;AAED,qBAAa,aAAc,SAAQ,KAAK;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;gBAAlB,QAAQ,EAAE,MAAM,EAAE;CAIxC;AA8CD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CA2LnE;AAED,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB;;CAA8B,CAAA"}
|
package/dist/manifest.js
CHANGED
|
@@ -25,6 +25,12 @@ class ManifestError extends Error {
|
|
|
25
25
|
exports.ManifestError = ManifestError;
|
|
26
26
|
const HANDLE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
27
27
|
const SLUG = /^[a-z0-9]+(?:[-_][a-z0-9]+)*$/;
|
|
28
|
+
/**
|
|
29
|
+
* Capability families whose member names are the platform's to define. The
|
|
30
|
+
* prefix is validated here; everything after the colon is checked against the
|
|
31
|
+
* live registry server-side.
|
|
32
|
+
*/
|
|
33
|
+
const NAMESPACED_CAPABILITY_FAMILIES = ['notification-override', 'notification-channel'];
|
|
28
34
|
function isHttpsUrl(value, { allowLocalhost = false } = {}) {
|
|
29
35
|
if (typeof value !== 'string')
|
|
30
36
|
return false;
|
|
@@ -41,6 +47,22 @@ function isHttpsUrl(value, { allowLocalhost = false } = {}) {
|
|
|
41
47
|
// never sent to it, and requiring TLS on a laptop is friction with no payoff.
|
|
42
48
|
return (allowLocalhost && url.protocol === 'http:' && /^(localhost|127\.0\.0\.1)$/.test(url.hostname));
|
|
43
49
|
}
|
|
50
|
+
/** Hosts that resolve to the machine making the call — never the app's server. */
|
|
51
|
+
function isLoopbackHost(value) {
|
|
52
|
+
let host;
|
|
53
|
+
try {
|
|
54
|
+
host = new URL(value).hostname.toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return (host === 'localhost' ||
|
|
60
|
+
host.endsWith('.localhost') ||
|
|
61
|
+
host === '127.0.0.1' ||
|
|
62
|
+
host === '::1' ||
|
|
63
|
+
host === '[::1]' ||
|
|
64
|
+
host === '0.0.0.0');
|
|
65
|
+
}
|
|
44
66
|
/**
|
|
45
67
|
* Parse and validate a manifest.
|
|
46
68
|
*
|
|
@@ -156,6 +178,7 @@ function parseAppManifest(input) {
|
|
|
156
178
|
problems.push('`iframe.width` must be "full" or "centered"');
|
|
157
179
|
}
|
|
158
180
|
}
|
|
181
|
+
let requestsNotificationCapability = false;
|
|
159
182
|
if (manifest.provides !== undefined) {
|
|
160
183
|
if (!Array.isArray(manifest.provides) || manifest.provides.some((c) => typeof c !== 'string')) {
|
|
161
184
|
problems.push('`provides` must be an array of capability names');
|
|
@@ -163,8 +186,27 @@ function parseAppManifest(input) {
|
|
|
163
186
|
else {
|
|
164
187
|
const seen = new Set();
|
|
165
188
|
for (const capability of manifest.provides) {
|
|
166
|
-
|
|
167
|
-
|
|
189
|
+
const colon = capability.indexOf(':');
|
|
190
|
+
if (colon === -1) {
|
|
191
|
+
if (!SLUG.test(capability)) {
|
|
192
|
+
problems.push(`\`provides\` entry "${capability}" must be a lowercase slug — capabilities come from Tanqory's closed vocabulary and review grants each one`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Namespaced: the family is ours to check, the name is the
|
|
197
|
+
// platform's. Both halves must still be present and well-formed —
|
|
198
|
+
// "notification-override:" reviews cleanly and overrides nothing.
|
|
199
|
+
const family = capability.slice(0, colon);
|
|
200
|
+
const name = capability.slice(colon + 1);
|
|
201
|
+
if (!NAMESPACED_CAPABILITY_FAMILIES.includes(family)) {
|
|
202
|
+
problems.push(`\`provides\` entry "${capability}" uses an unknown capability family "${family}" — namespaced capabilities are ${NAMESPACED_CAPABILITY_FAMILIES.map((f) => `${f}:<name>`).join(' or ')}`);
|
|
203
|
+
}
|
|
204
|
+
else if (!SLUG.test(name)) {
|
|
205
|
+
problems.push(`\`provides\` entry "${capability}" must name a ${family === 'notification-channel' ? 'channel' : 'notification type'} after the colon, as a lowercase slug (e.g. "${family}:${family === 'notification-channel' ? 'line' : 'order_new'}")`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
requestsNotificationCapability = true;
|
|
209
|
+
}
|
|
168
210
|
}
|
|
169
211
|
if (seen.has(capability))
|
|
170
212
|
problems.push(`\`provides\` lists "${capability}" more than once`);
|
|
@@ -172,6 +214,19 @@ function parseAppManifest(input) {
|
|
|
172
214
|
}
|
|
173
215
|
}
|
|
174
216
|
}
|
|
217
|
+
if (manifest.notifications !== undefined) {
|
|
218
|
+
const notifications = manifest.notifications;
|
|
219
|
+
// Localhost is refused even though `devUrl` allows it: this URL is called
|
|
220
|
+
// by the platform, not opened by a browser, so a laptop address here is
|
|
221
|
+
// one nothing can ever reach.
|
|
222
|
+
if (!isHttpsUrl(notifications?.dispatchUrl) ||
|
|
223
|
+
isLoopbackHost(notifications.dispatchUrl)) {
|
|
224
|
+
problems.push('`notifications.dispatchUrl` must be an https URL the platform can reach (not localhost — Tanqory calls it, your browser does not)');
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (requestsNotificationCapability) {
|
|
228
|
+
problems.push('`notifications.dispatchUrl` is required when `provides` names a notification-override or notification-channel capability — otherwise the messages you took over have nowhere to go');
|
|
229
|
+
}
|
|
175
230
|
if (problems.length > 0)
|
|
176
231
|
throw new ManifestError(problems);
|
|
177
232
|
return manifest;
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The JSON Schema and `parseAppManifest` must agree.
|
|
3
|
+
*
|
|
4
|
+
* `parseAppManifest` is hand-written on purpose — this package is installed by
|
|
5
|
+
* strangers, and a schema library would be one more dependency they are asked to
|
|
6
|
+
* trust. So the schema shipped for editors and agents cannot be derived from it;
|
|
7
|
+
* it is written alongside, and would drift the moment anyone changed one and not
|
|
8
|
+
* the other.
|
|
9
|
+
*
|
|
10
|
+
* This is what stops that. Every case runs through both, and the two must reach
|
|
11
|
+
* the same verdict. A rule added to one and forgotten in the other fails here
|
|
12
|
+
* rather than in someone's editor six weeks later, telling them a manifest is
|
|
13
|
+
* fine that submission will reject.
|
|
14
|
+
*
|
|
15
|
+
* `ajv` is a devDependency. Nothing here ships.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=manifest.schema.spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.schema.spec.d.ts","sourceRoot":"","sources":["../src/manifest.schema.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The JSON Schema and `parseAppManifest` must agree.
|
|
4
|
+
*
|
|
5
|
+
* `parseAppManifest` is hand-written on purpose — this package is installed by
|
|
6
|
+
* strangers, and a schema library would be one more dependency they are asked to
|
|
7
|
+
* trust. So the schema shipped for editors and agents cannot be derived from it;
|
|
8
|
+
* it is written alongside, and would drift the moment anyone changed one and not
|
|
9
|
+
* the other.
|
|
10
|
+
*
|
|
11
|
+
* This is what stops that. Every case runs through both, and the two must reach
|
|
12
|
+
* the same verdict. A rule added to one and forgotten in the other fails here
|
|
13
|
+
* rather than in someone's editor six weeks later, telling them a manifest is
|
|
14
|
+
* fine that submission will reject.
|
|
15
|
+
*
|
|
16
|
+
* `ajv` is a devDependency. Nothing here ships.
|
|
17
|
+
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
const node_fs_1 = require("node:fs");
|
|
23
|
+
const node_path_1 = require("node:path");
|
|
24
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
25
|
+
const vitest_1 = require("vitest");
|
|
26
|
+
const manifest_1 = require("./manifest");
|
|
27
|
+
const schema = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, '..', 'schema', 'tanqory-app.schema.json'), 'utf8'));
|
|
28
|
+
const ajv = new ajv_1.default({ allErrors: true, strict: false });
|
|
29
|
+
const validateWithSchema = ajv.compile(schema);
|
|
30
|
+
const VALID = {
|
|
31
|
+
handle: 'order-notifier',
|
|
32
|
+
name: 'Order Notifier',
|
|
33
|
+
appUrl: 'https://order-notifier.example.com',
|
|
34
|
+
devUrl: 'http://localhost:3000',
|
|
35
|
+
embedded: { enabled: true, path: '/embed' },
|
|
36
|
+
scopes: ['orders.view'],
|
|
37
|
+
webhooks: [{ topic: 'orders/create', path: '/hooks/orders' }],
|
|
38
|
+
};
|
|
39
|
+
/** What each side says about the same input. */
|
|
40
|
+
function verdicts(manifest) {
|
|
41
|
+
let validator = true;
|
|
42
|
+
try {
|
|
43
|
+
(0, manifest_1.parseAppManifest)(manifest);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
validator = false;
|
|
47
|
+
}
|
|
48
|
+
return { schema: validateWithSchema(manifest), validator };
|
|
49
|
+
}
|
|
50
|
+
const cases = [
|
|
51
|
+
['the scaffold default', VALID, true],
|
|
52
|
+
['no devUrl', { ...VALID, devUrl: undefined }, true],
|
|
53
|
+
[
|
|
54
|
+
'a manifest with every optional field',
|
|
55
|
+
{
|
|
56
|
+
...VALID,
|
|
57
|
+
supportUrl: 'https://example.com/support',
|
|
58
|
+
privacyPolicyUrl: 'https://example.com/privacy',
|
|
59
|
+
appType: 'embed',
|
|
60
|
+
navigation: { placement: 'orders', items: [{ label: 'Settings', path: '/embed/settings' }] },
|
|
61
|
+
iframe: { minHeight: 600, width: 'full' },
|
|
62
|
+
},
|
|
63
|
+
true,
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
'notification capability with a dispatchUrl',
|
|
67
|
+
{
|
|
68
|
+
...VALID,
|
|
69
|
+
provides: ['notification-channel:sms'],
|
|
70
|
+
notifications: { dispatchUrl: 'https://example.com/dispatch' },
|
|
71
|
+
},
|
|
72
|
+
true,
|
|
73
|
+
],
|
|
74
|
+
['an uppercase handle', { ...VALID, handle: 'OrderNotifier' }, false],
|
|
75
|
+
['a handle with spaces', { ...VALID, handle: 'order notifier' }, false],
|
|
76
|
+
['a leading hyphen in the handle', { ...VALID, handle: '-order' }, false],
|
|
77
|
+
['no handle at all', { ...VALID, handle: undefined }, false],
|
|
78
|
+
['an empty name', { ...VALID, name: '' }, false],
|
|
79
|
+
['a plain http appUrl', { ...VALID, appUrl: 'http://example.com' }, false],
|
|
80
|
+
[
|
|
81
|
+
'a devUrl on plain http that is not localhost',
|
|
82
|
+
{ ...VALID, devUrl: 'http://example.com' },
|
|
83
|
+
false,
|
|
84
|
+
],
|
|
85
|
+
['scopes as a string', { ...VALID, scopes: 'orders.view' }, false],
|
|
86
|
+
['a duplicated scope', { ...VALID, scopes: ['orders.view', 'orders.view'] }, false],
|
|
87
|
+
[
|
|
88
|
+
'an embedded.path with no leading slash',
|
|
89
|
+
{ ...VALID, embedded: { enabled: true, path: 'embed' } },
|
|
90
|
+
false,
|
|
91
|
+
],
|
|
92
|
+
['embedded.enabled as a string', { ...VALID, embedded: { enabled: 'yes' } }, false],
|
|
93
|
+
[
|
|
94
|
+
'a webhook path with no leading slash',
|
|
95
|
+
{ ...VALID, webhooks: [{ topic: 'orders/create', path: 'hooks' }] },
|
|
96
|
+
false,
|
|
97
|
+
],
|
|
98
|
+
['a webhook with no topic', { ...VALID, webhooks: [{ path: '/hooks' }] }, false],
|
|
99
|
+
['appType outside the enum', { ...VALID, appType: 'popup' }, false],
|
|
100
|
+
['iframe.width outside the enum', { ...VALID, iframe: { width: 'wide' } }, false],
|
|
101
|
+
['a negative iframe.minHeight', { ...VALID, iframe: { minHeight: -1 } }, false],
|
|
102
|
+
['navigation with no placement', { ...VALID, navigation: { items: [] } }, false],
|
|
103
|
+
[
|
|
104
|
+
'a navigation item with no label',
|
|
105
|
+
{ ...VALID, navigation: { placement: 'orders', items: [{ path: '/embed' }] } },
|
|
106
|
+
false,
|
|
107
|
+
],
|
|
108
|
+
// The field that never existed but shipped in an early first-party manifest.
|
|
109
|
+
// Rejected by name so the fix is obvious rather than silently ignored.
|
|
110
|
+
['the legacy embeddedPath field', { ...VALID, embeddedPath: '/embed' }, false],
|
|
111
|
+
// Taking over a notification with nowhere for it to go.
|
|
112
|
+
[
|
|
113
|
+
'a notification capability with no dispatchUrl',
|
|
114
|
+
{ ...VALID, provides: ['notification-override:order_confirmation'] },
|
|
115
|
+
false,
|
|
116
|
+
],
|
|
117
|
+
[
|
|
118
|
+
'a dispatchUrl on localhost',
|
|
119
|
+
{
|
|
120
|
+
...VALID,
|
|
121
|
+
provides: ['notification-channel:sms'],
|
|
122
|
+
notifications: { dispatchUrl: 'http://localhost:3000/dispatch' },
|
|
123
|
+
},
|
|
124
|
+
false,
|
|
125
|
+
],
|
|
126
|
+
];
|
|
127
|
+
(0, vitest_1.describe)('the JSON Schema agrees with parseAppManifest', () => {
|
|
128
|
+
vitest_1.it.each(cases)('%s', (_label, manifest, expected) => {
|
|
129
|
+
const { schema: bySchema, validator: byValidator } = verdicts(manifest);
|
|
130
|
+
// The assertion that matters is that they agree. Comparing both to the
|
|
131
|
+
// expectation separately would let a case pass while the two disagreed
|
|
132
|
+
// about why.
|
|
133
|
+
(0, vitest_1.expect)({ schema: bySchema, validator: byValidator }).toEqual({
|
|
134
|
+
schema: expected,
|
|
135
|
+
validator: expected,
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
(0, vitest_1.it)('lists every field the type declares, so a new one cannot be forgotten', () => {
|
|
139
|
+
// `additionalProperties: false` means a field added to the type but not to
|
|
140
|
+
// the schema is rejected by an editor while submission accepts it — the
|
|
141
|
+
// drift that is hardest to spot, because the tool is wrong and the platform
|
|
142
|
+
// is right.
|
|
143
|
+
const declared = Object.keys(schema.properties).sort();
|
|
144
|
+
(0, vitest_1.expect)(declared).toEqual([
|
|
145
|
+
'$schema',
|
|
146
|
+
'appType',
|
|
147
|
+
'appUrl',
|
|
148
|
+
'devUrl',
|
|
149
|
+
'embedded',
|
|
150
|
+
'embeddedPath',
|
|
151
|
+
'handle',
|
|
152
|
+
'iframe',
|
|
153
|
+
'name',
|
|
154
|
+
'navigation',
|
|
155
|
+
'notifications',
|
|
156
|
+
'privacyPolicyUrl',
|
|
157
|
+
'provides',
|
|
158
|
+
'scopes',
|
|
159
|
+
'supportUrl',
|
|
160
|
+
'webhooks',
|
|
161
|
+
].sort());
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=manifest.schema.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.schema.spec.js","sourceRoot":"","sources":["../src/manifest.schema.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest.spec.js
CHANGED
|
@@ -129,5 +129,65 @@ function problemsOf(input) {
|
|
|
129
129
|
(0, vitest_1.expect)(problemsOf({ ...VALID, provides: ['marketing-suite'] })).toEqual([]);
|
|
130
130
|
});
|
|
131
131
|
});
|
|
132
|
+
(0, vitest_1.describe)('notification capabilities', () => {
|
|
133
|
+
const NOTIFY = { dispatchUrl: 'https://hooks.example.com/tanqory/notifications' };
|
|
134
|
+
(0, vitest_1.it)('accepts an override and a channel alongside a plain capability', () => {
|
|
135
|
+
(0, vitest_1.expect)(problemsOf({
|
|
136
|
+
...VALID,
|
|
137
|
+
provides: [
|
|
138
|
+
'marketing-suite',
|
|
139
|
+
'notification-override:order_new',
|
|
140
|
+
'notification-channel:line',
|
|
141
|
+
],
|
|
142
|
+
notifications: NOTIFY,
|
|
143
|
+
})).toEqual([]);
|
|
144
|
+
});
|
|
145
|
+
(0, vitest_1.it)('passes an unknown type or channel name — that vocabulary is the platform’s', () => {
|
|
146
|
+
// Shape-valid but not in today's registry. The SDK lets it through for
|
|
147
|
+
// the same reason it lets an unknown nav placement through: the list
|
|
148
|
+
// lives server-side and must grow without an SDK release.
|
|
149
|
+
(0, vitest_1.expect)(problemsOf({
|
|
150
|
+
...VALID,
|
|
151
|
+
provides: ['notification-override:some_future_type'],
|
|
152
|
+
notifications: NOTIFY,
|
|
153
|
+
})).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
(0, vitest_1.it)('rejects an unknown capability family', () => {
|
|
156
|
+
const problems = problemsOf({
|
|
157
|
+
...VALID,
|
|
158
|
+
provides: ['notification-takeover:order_new'],
|
|
159
|
+
notifications: NOTIFY,
|
|
160
|
+
});
|
|
161
|
+
(0, vitest_1.expect)(problems.join(' ')).toContain('notification-takeover');
|
|
162
|
+
(0, vitest_1.expect)(problems.join(' ')).toContain('notification-override:<name>');
|
|
163
|
+
});
|
|
164
|
+
vitest_1.it.each([
|
|
165
|
+
['an empty name', 'notification-override:'],
|
|
166
|
+
['an uppercase name', 'notification-channel:LINE'],
|
|
167
|
+
['a spaced name', 'notification-override:order new'],
|
|
168
|
+
['a second colon', 'notification-override:order:new'],
|
|
169
|
+
])('rejects %s', (_label, capability) => {
|
|
170
|
+
(0, vitest_1.expect)(problemsOf({ ...VALID, provides: [capability], notifications: NOTIFY })).not.toEqual([]);
|
|
171
|
+
});
|
|
172
|
+
(0, vitest_1.it)('requires a dispatchUrl once a notification capability is declared', () => {
|
|
173
|
+
// A takeover with nowhere to deliver drops every message it claimed —
|
|
174
|
+
// the one failure mode a merchant would never see in the UI.
|
|
175
|
+
const problems = problemsOf({ ...VALID, provides: ['notification-override:order_new'] });
|
|
176
|
+
(0, vitest_1.expect)(problems.join(' ')).toContain('notifications.dispatchUrl');
|
|
177
|
+
});
|
|
178
|
+
(0, vitest_1.it)('does not require a dispatchUrl for a plain capability', () => {
|
|
179
|
+
(0, vitest_1.expect)(problemsOf({ ...VALID, provides: ['marketing-suite'] })).toEqual([]);
|
|
180
|
+
});
|
|
181
|
+
vitest_1.it.each([
|
|
182
|
+
['http', 'http://hooks.example.com/n'],
|
|
183
|
+
['localhost', 'https://localhost:3000/n'],
|
|
184
|
+
['a loopback ip', 'https://127.0.0.1/n'],
|
|
185
|
+
['not a URL at all', '/notifications'],
|
|
186
|
+
])('rejects a dispatchUrl on %s', (_label, dispatchUrl) => {
|
|
187
|
+
// Unlike `devUrl`, this URL is called BY Tanqory. A laptop address here
|
|
188
|
+
// is one nothing can ever reach, so it is refused rather than tolerated.
|
|
189
|
+
(0, vitest_1.expect)(problemsOf({ ...VALID, notifications: { dispatchUrl } })).not.toEqual([]);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
132
192
|
});
|
|
133
193
|
//# sourceMappingURL=manifest.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.spec.js","sourceRoot":"","sources":["../src/manifest.spec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manifest.spec.js","sourceRoot":"","sources":["../src/manifest.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanqory/plugin-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/tanqory/tanqory-platform-packages.git",
|
|
@@ -29,10 +29,12 @@
|
|
|
29
29
|
"./client": {
|
|
30
30
|
"types": "./dist/client/index.d.ts",
|
|
31
31
|
"default": "./dist/client/index.js"
|
|
32
|
-
}
|
|
32
|
+
},
|
|
33
|
+
"./schema/tanqory-app.schema.json": "./schema/tanqory-app.schema.json"
|
|
33
34
|
},
|
|
34
35
|
"files": [
|
|
35
36
|
"dist",
|
|
37
|
+
"schema",
|
|
36
38
|
"README.md"
|
|
37
39
|
],
|
|
38
40
|
"scripts": {
|
|
@@ -56,6 +58,7 @@
|
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@types/node": "^20.0.0",
|
|
58
60
|
"@types/react": "^18.0.0",
|
|
61
|
+
"ajv": "^8.17.1",
|
|
59
62
|
"react": "^18.0.0",
|
|
60
63
|
"typescript": "^5.9.3",
|
|
61
64
|
"vitest": "^3.2.6"
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://unpkg.com/@tanqory/plugin-sdk/schema/tanqory-app.schema.json",
|
|
4
|
+
"title": "Tanqory app manifest",
|
|
5
|
+
"description": "tanqory.app.json — the contract a merchant consents to. Hand-maintained alongside parseAppManifest; manifest.schema.spec.ts asserts the two agree on every case.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["handle", "name", "appUrl", "scopes"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Editor hint only. Ignored by the platform."
|
|
13
|
+
},
|
|
14
|
+
"handle": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
|
|
17
|
+
"description": "Immutable global identity, and part of every install link. Lowercase letters, digits and single hyphens."
|
|
18
|
+
},
|
|
19
|
+
"name": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"minLength": 1,
|
|
22
|
+
"description": "Display name. Editable, unlike the handle."
|
|
23
|
+
},
|
|
24
|
+
"appUrl": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^https://",
|
|
27
|
+
"description": "Where merchants are pointed. Must be https."
|
|
28
|
+
},
|
|
29
|
+
"devUrl": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"pattern": "^(https://|http://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?(/|$))",
|
|
32
|
+
"description": "Framed instead of appUrl on a development-store test install. Plain http is allowed here, and only here, so localhost works."
|
|
33
|
+
},
|
|
34
|
+
"embedded": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"required": ["enabled"],
|
|
38
|
+
"properties": {
|
|
39
|
+
"enabled": { "type": "boolean" },
|
|
40
|
+
"path": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"pattern": "^/",
|
|
43
|
+
"description": "Entry point the dashboard frames. The route beneath it must carry a [storeId] segment."
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"embeddedPath": {
|
|
48
|
+
"not": {},
|
|
49
|
+
"description": "Not a manifest field. Use embedded: { enabled: true, path: \"...\" }. Declared here so an editor rejects it by name rather than ignoring it."
|
|
50
|
+
},
|
|
51
|
+
"scopes": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"uniqueItems": true,
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"pattern": "^[a-z_]+\\.[a-z_]+$",
|
|
57
|
+
"description": "domain.action, from the closed catalogue at https://docs.tanqory.com/apps/scopes/. There is no read_* form."
|
|
58
|
+
},
|
|
59
|
+
"description": "What the install screen asks for. The token is capped to what was actually granted."
|
|
60
|
+
},
|
|
61
|
+
"webhooks": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["topic", "path"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"topic": { "type": "string", "minLength": 1 },
|
|
69
|
+
"path": { "type": "string", "pattern": "^/" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"supportUrl": { "type": "string", "pattern": "^https://" },
|
|
74
|
+
"privacyPolicyUrl": { "type": "string", "pattern": "^https://" },
|
|
75
|
+
"appType": {
|
|
76
|
+
"enum": ["embed", "external"],
|
|
77
|
+
"description": "external means open in a new tab, not iframe."
|
|
78
|
+
},
|
|
79
|
+
"navigation": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"additionalProperties": false,
|
|
82
|
+
"required": ["placement"],
|
|
83
|
+
"properties": {
|
|
84
|
+
"placement": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"description": "Which dashboard menu the app appears under. Shape-checked here and resolved server-side, so the slot list can grow without an SDK release.",
|
|
87
|
+
"examples": [
|
|
88
|
+
"apps",
|
|
89
|
+
"orders",
|
|
90
|
+
"products",
|
|
91
|
+
"customers",
|
|
92
|
+
"marketing",
|
|
93
|
+
"content",
|
|
94
|
+
"analytics",
|
|
95
|
+
"discounts",
|
|
96
|
+
"store-automation",
|
|
97
|
+
"online-store",
|
|
98
|
+
"subscriptions",
|
|
99
|
+
"markets"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"items": {
|
|
103
|
+
"type": "array",
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": false,
|
|
107
|
+
"required": ["label", "path"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"label": { "type": "string", "minLength": 1 },
|
|
110
|
+
"path": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"pattern": "^/",
|
|
113
|
+
"description": "Resolves inside your embedded surface. Declaring it does not create the route."
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"iframe": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"additionalProperties": false,
|
|
123
|
+
"properties": {
|
|
124
|
+
"minHeight": { "type": "number", "exclusiveMinimum": 0 },
|
|
125
|
+
"width": { "enum": ["full", "centered"] }
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"provides": {
|
|
129
|
+
"type": "array",
|
|
130
|
+
"uniqueItems": true,
|
|
131
|
+
"items": {
|
|
132
|
+
"type": "string",
|
|
133
|
+
"description": "A bare capability slug, or a namespaced notification-override:<type> / notification-channel:<channel>. The family is checked here; the name is checked against a live registry at submission."
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"notifications": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"additionalProperties": false,
|
|
139
|
+
"required": ["dispatchUrl"],
|
|
140
|
+
"properties": {
|
|
141
|
+
"dispatchUrl": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"pattern": "^https://",
|
|
144
|
+
"description": "Where Tanqory posts a message you took over. Must be reachable from the platform — not localhost, because Tanqory calls it, your browser does not."
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"allOf": [
|
|
150
|
+
{
|
|
151
|
+
"$comment": "provides naming a notification capability requires notifications.dispatchUrl — otherwise the messages you took over have nowhere to go.",
|
|
152
|
+
"if": {
|
|
153
|
+
"properties": {
|
|
154
|
+
"provides": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"contains": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"pattern": "^notification-(override|channel):"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"required": ["provides"]
|
|
163
|
+
},
|
|
164
|
+
"then": { "required": ["notifications"] }
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
}
|