@proveanything/smartlinks 2.0.21 → 2.0.24
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/api/functions.d.ts +8 -1
- package/dist/api/functions.js +11 -8
- package/dist/context.d.ts +18 -0
- package/dist/context.js +48 -0
- package/dist/docs/API_SUMMARY.md +74 -3
- package/dist/docs/app-manifest.md +34 -0
- package/dist/docs/server-functions.md +51 -16
- package/dist/http.d.ts +8 -0
- package/dist/http.js +33 -0
- package/dist/iframe.d.ts +14 -0
- package/dist/iframe.js +43 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/openapi.yaml +111 -2
- package/dist/testing/index.d.ts +19 -0
- package/dist/testing/index.js +30 -0
- package/dist/types/appManifest.d.ts +127 -2
- package/docs/API_SUMMARY.md +74 -3
- package/docs/app-manifest.md +34 -0
- package/docs/server-functions.md +51 -16
- package/openapi.yaml +111 -2
- package/package.json +1 -1
package/dist/openapi.yaml
CHANGED
|
@@ -18255,6 +18255,11 @@ components:
|
|
|
18255
18255
|
type: array
|
|
18256
18256
|
items:
|
|
18257
18257
|
type: string
|
|
18258
|
+
dataScope:
|
|
18259
|
+
type: string
|
|
18260
|
+
enum:
|
|
18261
|
+
- collection
|
|
18262
|
+
- global
|
|
18258
18263
|
apiVersion:
|
|
18259
18264
|
type: string
|
|
18260
18265
|
handler:
|
|
@@ -18274,6 +18279,41 @@ components:
|
|
|
18274
18279
|
required:
|
|
18275
18280
|
- files
|
|
18276
18281
|
- definitions
|
|
18282
|
+
AppDataOpts:
|
|
18283
|
+
type: object
|
|
18284
|
+
properties:
|
|
18285
|
+
scope:
|
|
18286
|
+
type: string
|
|
18287
|
+
enum:
|
|
18288
|
+
- collection
|
|
18289
|
+
- global
|
|
18290
|
+
productId:
|
|
18291
|
+
type: string
|
|
18292
|
+
variantId:
|
|
18293
|
+
type: string
|
|
18294
|
+
batchId:
|
|
18295
|
+
type: string
|
|
18296
|
+
dataId:
|
|
18297
|
+
type: string
|
|
18298
|
+
queries:
|
|
18299
|
+
type: object
|
|
18300
|
+
additionalProperties: true
|
|
18301
|
+
AppDataHandle:
|
|
18302
|
+
type: object
|
|
18303
|
+
properties: {}
|
|
18304
|
+
ServerFunctionSl:
|
|
18305
|
+
type: object
|
|
18306
|
+
properties:
|
|
18307
|
+
appRecords: {}
|
|
18308
|
+
products: {}
|
|
18309
|
+
attestations: {}
|
|
18310
|
+
appData:
|
|
18311
|
+
$ref: "#/components/schemas/AppDataHandle"
|
|
18312
|
+
required:
|
|
18313
|
+
- appRecords
|
|
18314
|
+
- products
|
|
18315
|
+
- attestations
|
|
18316
|
+
- appData
|
|
18277
18317
|
ServerFunctionCaller:
|
|
18278
18318
|
type: object
|
|
18279
18319
|
properties:
|
|
@@ -18298,7 +18338,8 @@ components:
|
|
|
18298
18338
|
type: string
|
|
18299
18339
|
appId:
|
|
18300
18340
|
type: string
|
|
18301
|
-
sl:
|
|
18341
|
+
sl:
|
|
18342
|
+
$ref: "#/components/schemas/ServerFunctionSl"
|
|
18302
18343
|
secrets:
|
|
18303
18344
|
type: object
|
|
18304
18345
|
additionalProperties: true
|
|
@@ -18314,6 +18355,30 @@ components:
|
|
|
18314
18355
|
- secrets
|
|
18315
18356
|
- caller
|
|
18316
18357
|
- fetch
|
|
18358
|
+
ServerFunctionHttpEvent:
|
|
18359
|
+
type: object
|
|
18360
|
+
properties:
|
|
18361
|
+
method:
|
|
18362
|
+
type: string
|
|
18363
|
+
body:
|
|
18364
|
+
type: object
|
|
18365
|
+
additionalProperties: true
|
|
18366
|
+
query:
|
|
18367
|
+
type: object
|
|
18368
|
+
additionalProperties: true
|
|
18369
|
+
headers:
|
|
18370
|
+
type: object
|
|
18371
|
+
additionalProperties: true
|
|
18372
|
+
rawBody:
|
|
18373
|
+
type: object
|
|
18374
|
+
additionalProperties: true
|
|
18375
|
+
contentType:
|
|
18376
|
+
type: string
|
|
18377
|
+
required:
|
|
18378
|
+
- method
|
|
18379
|
+
- body
|
|
18380
|
+
- query
|
|
18381
|
+
- headers
|
|
18317
18382
|
AppAdminConfig:
|
|
18318
18383
|
type: object
|
|
18319
18384
|
properties:
|
|
@@ -18397,6 +18462,40 @@ components:
|
|
|
18397
18462
|
- scope
|
|
18398
18463
|
- name
|
|
18399
18464
|
- type
|
|
18465
|
+
PublicViewParams:
|
|
18466
|
+
type: object
|
|
18467
|
+
properties:
|
|
18468
|
+
required:
|
|
18469
|
+
type: array
|
|
18470
|
+
items:
|
|
18471
|
+
type: string
|
|
18472
|
+
optional:
|
|
18473
|
+
type: array
|
|
18474
|
+
items:
|
|
18475
|
+
type: string
|
|
18476
|
+
PublicView:
|
|
18477
|
+
type: object
|
|
18478
|
+
properties:
|
|
18479
|
+
id:
|
|
18480
|
+
type: string
|
|
18481
|
+
title:
|
|
18482
|
+
type: string
|
|
18483
|
+
kind:
|
|
18484
|
+
$ref: "#/components/schemas/PublicViewKind"
|
|
18485
|
+
route:
|
|
18486
|
+
type: string
|
|
18487
|
+
set:
|
|
18488
|
+
type: object
|
|
18489
|
+
additionalProperties:
|
|
18490
|
+
type: string
|
|
18491
|
+
params:
|
|
18492
|
+
$ref: "#/components/schemas/PublicViewParams"
|
|
18493
|
+
default:
|
|
18494
|
+
type: boolean
|
|
18495
|
+
required:
|
|
18496
|
+
- id
|
|
18497
|
+
- title
|
|
18498
|
+
- kind
|
|
18400
18499
|
AppManifest:
|
|
18401
18500
|
type: object
|
|
18402
18501
|
properties:
|
|
@@ -18472,6 +18571,10 @@ components:
|
|
|
18472
18571
|
type: array
|
|
18473
18572
|
items:
|
|
18474
18573
|
$ref: "#/components/schemas/DeepLinkEntry"
|
|
18574
|
+
publicViews:
|
|
18575
|
+
type: array
|
|
18576
|
+
items:
|
|
18577
|
+
$ref: "#/components/schemas/PublicView"
|
|
18475
18578
|
executor:
|
|
18476
18579
|
$ref: "#/components/schemas/AppManifestExecutor"
|
|
18477
18580
|
functions:
|
|
@@ -18532,6 +18635,11 @@ components:
|
|
|
18532
18635
|
enum:
|
|
18533
18636
|
- caller
|
|
18534
18637
|
- collection
|
|
18638
|
+
PublicViewKind:
|
|
18639
|
+
type: string
|
|
18640
|
+
enum:
|
|
18641
|
+
- contextual
|
|
18642
|
+
- standalone
|
|
18535
18643
|
PaginatedResponse:
|
|
18536
18644
|
type: object
|
|
18537
18645
|
properties:
|
|
@@ -29290,7 +29398,8 @@ components:
|
|
|
29290
29398
|
type: object
|
|
29291
29399
|
properties:
|
|
29292
29400
|
appId:
|
|
29293
|
-
type:
|
|
29401
|
+
type: object
|
|
29402
|
+
additionalProperties: true
|
|
29294
29403
|
AllocateSequenceInput:
|
|
29295
29404
|
type: object
|
|
29296
29405
|
properties:
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -24,6 +24,25 @@ export interface TestSlImpl {
|
|
|
24
24
|
attestations?: {
|
|
25
25
|
create?(fields: any): any;
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* THIS app's own data. Provide impls to assert calls, or omit to use a built-in in-memory store
|
|
29
|
+
* (so a counter test actually persists across calls within the test). `.global`/`.collection` and
|
|
30
|
+
* per-call `{ scope }` share the same store in the harness.
|
|
31
|
+
*/
|
|
32
|
+
appData?: {
|
|
33
|
+
get?(opts?: any): any;
|
|
34
|
+
set?(data: any, opts?: any): any;
|
|
35
|
+
getData?(opts?: any): any;
|
|
36
|
+
setData?(data: any, opts?: any): any;
|
|
37
|
+
delete?(opts?: any): any;
|
|
38
|
+
};
|
|
39
|
+
/** Cross-app reads: return another app's data as the caller would see it. Keyed by appId. */
|
|
40
|
+
app?: (appId: string) => {
|
|
41
|
+
data?: {
|
|
42
|
+
get?(opts?: any): any;
|
|
43
|
+
getData?(opts?: any): any;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
27
46
|
}
|
|
28
47
|
export interface TestCaller {
|
|
29
48
|
userId?: string | null;
|
package/dist/testing/index.js
CHANGED
|
@@ -102,6 +102,36 @@ export function createFunctionTestContext(opts) {
|
|
|
102
102
|
create: gated('attestations', 'write', at.create && at.create.bind(at), 'create'),
|
|
103
103
|
},
|
|
104
104
|
};
|
|
105
|
+
// appData — own-data (capability-gated only, no role gate). Delegates to a provided impl, else a
|
|
106
|
+
// built-in in-memory store so read-modify-write (e.g. a counter) works across calls in one test.
|
|
107
|
+
const ad = impl.appData || {};
|
|
108
|
+
const memConfig = {};
|
|
109
|
+
const memData = {};
|
|
110
|
+
const deepMerge = (t, s) => { for (const k of Object.keys(s || {}))
|
|
111
|
+
t[k] = (s[k] && typeof s[k] === 'object' && !Array.isArray(s[k])) ? deepMerge(t[k] || {}, s[k]) : s[k]; return t; };
|
|
112
|
+
const makeAppData = () => ({
|
|
113
|
+
get: gated('data', 'read', ad.get ? ad.get.bind(ad) : (async () => (Object.assign({}, memConfig))), 'get'),
|
|
114
|
+
set: gated('data', 'write', ad.set ? ad.set.bind(ad) : (async (data) => deepMerge(memConfig, data)), 'set'),
|
|
115
|
+
getData: gated('data', 'read', ad.getData ? ad.getData.bind(ad) : (async (opts = {}) => (opts.dataId ? memData[opts.dataId] : Object.values(memData))), 'getData'),
|
|
116
|
+
setData: gated('data', 'write', ad.setData ? ad.setData.bind(ad) : (async (data, opts = {}) => { if (opts.dataId)
|
|
117
|
+
memData[opts.dataId] = data; return data; }), 'setData'),
|
|
118
|
+
delete: gated('data', 'write', ad.delete ? ad.delete.bind(ad) : (async (opts = {}) => { if (opts.dataId)
|
|
119
|
+
delete memData[opts.dataId];
|
|
120
|
+
else
|
|
121
|
+
for (const k of Object.keys(memConfig))
|
|
122
|
+
delete memConfig[k]; }), 'delete'),
|
|
123
|
+
});
|
|
124
|
+
sl.appData = Object.assign(makeAppData(), { global: makeAppData(), collection: makeAppData() });
|
|
125
|
+
sl.app = (appId) => {
|
|
126
|
+
const other = (impl.app && impl.app(appId)) || {};
|
|
127
|
+
const od = other.data || {};
|
|
128
|
+
return {
|
|
129
|
+
data: {
|
|
130
|
+
get: gated('data', 'read', od.get ? od.get.bind(od) : (async () => null), 'app.get'),
|
|
131
|
+
getData: gated('data', 'read', od.getData ? od.getData.bind(od) : (async () => []), 'app.getData'),
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
};
|
|
105
135
|
const secretsMap = opts.secrets || {};
|
|
106
136
|
const baseFetch = opts.fetch || (typeof fetch !== 'undefined' ? fetch : undefined);
|
|
107
137
|
const via = (def.trigger && def.trigger.type) || 'http';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
/**
|
|
2
4
|
* A bundle (widget or container) as returned by the collection widgets endpoint.
|
|
3
5
|
*
|
|
@@ -258,6 +260,13 @@ export interface AppFunctionDef {
|
|
|
258
260
|
* Grammar: `sl:<resource>:<read|write>`, `network` (or `network:<host>`), `secrets:<ref>`.
|
|
259
261
|
*/
|
|
260
262
|
capabilities?: string[];
|
|
263
|
+
/**
|
|
264
|
+
* Default scope for `ctx.sl.appData.*` — `'collection'` (this collection; the default) or
|
|
265
|
+
* `'global'` (the app's app-wide bucket, shared by every collection that installed it). A function
|
|
266
|
+
* whose data is global-by-intent declares `'global'` and then just uses `appData.get()/set()`.
|
|
267
|
+
* Per-call `{ scope }` and the `appData.global` / `appData.collection` handles override this.
|
|
268
|
+
*/
|
|
269
|
+
dataScope?: 'collection' | 'global';
|
|
261
270
|
/** SDK/manifest API version this function targets (pinned for runtime compatibility). */
|
|
262
271
|
apiVersion?: string;
|
|
263
272
|
/** Exported handler name in the functions bundle. Defaults to `name`. */
|
|
@@ -268,6 +277,57 @@ export interface AppManifestFunctions {
|
|
|
268
277
|
files: AppManifestFiles;
|
|
269
278
|
definitions: AppFunctionDef[];
|
|
270
279
|
}
|
|
280
|
+
/** Scope + selector options for `ctx.sl.appData.*`. */
|
|
281
|
+
export interface AppDataOpts {
|
|
282
|
+
/** `'collection'` (this collection) or `'global'` (the app's app-wide bucket). Defaults to the function's `dataScope`. */
|
|
283
|
+
scope?: 'collection' | 'global';
|
|
284
|
+
productId?: string;
|
|
285
|
+
variantId?: string;
|
|
286
|
+
batchId?: string;
|
|
287
|
+
/** For `getData`/`setData`/`delete`: the keyed data item id. */
|
|
288
|
+
dataId?: string;
|
|
289
|
+
queries?: Record<string, any>;
|
|
290
|
+
}
|
|
291
|
+
/** Read/write handle for an app's own durable data. `set` deep-merges the singleton config blob. */
|
|
292
|
+
export interface AppDataHandle {
|
|
293
|
+
get(opts?: AppDataOpts): Promise<any>;
|
|
294
|
+
set(data: any, opts?: AppDataOpts): Promise<any>;
|
|
295
|
+
getData(opts?: AppDataOpts): Promise<any>;
|
|
296
|
+
setData(data: any, opts?: AppDataOpts): Promise<any>;
|
|
297
|
+
delete(opts?: AppDataOpts): Promise<any>;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* The capability-gated SmartLinks surface handed to a server function. Two access modes:
|
|
301
|
+
* - by APP identity — `appData` / `appRecords` are THIS app's OWN data (any scope), gated by the
|
|
302
|
+
* declared capability only (the caller's role is irrelevant — it's the app's own namespace).
|
|
303
|
+
* - by CALLER identity — everything else (products, attestations, and `app(id)` cross-app reads)
|
|
304
|
+
* is bounded by what the invoking user could do through the permissioned API.
|
|
305
|
+
*/
|
|
306
|
+
export interface ServerFunctionSl {
|
|
307
|
+
/** THIS app's records (own namespace). */
|
|
308
|
+
appRecords: any;
|
|
309
|
+
/** Products, scoped by caller authority + declared capability. */
|
|
310
|
+
products: any;
|
|
311
|
+
/** Attestations, scoped by caller authority + declared capability. */
|
|
312
|
+
attestations: any;
|
|
313
|
+
/**
|
|
314
|
+
* THIS app's durable data/config. Default scope follows the function's declared `dataScope`
|
|
315
|
+
* (else `collection`). `appData.global` / `appData.collection` force a scope regardless.
|
|
316
|
+
* Own-data access is gated by `sl:data:read` / `sl:data:write` only.
|
|
317
|
+
*/
|
|
318
|
+
appData: AppDataHandle & {
|
|
319
|
+
global: AppDataHandle;
|
|
320
|
+
collection: AppDataHandle;
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Read ANOTHER app's data in this collection, by CALLER identity — only what the invoking user
|
|
324
|
+
* could read (admin sees all; otherwise public-filtered, private fields stripped). Read-only;
|
|
325
|
+
* never another app's private/global store, never another collection. Gated by `sl:data:read`.
|
|
326
|
+
*/
|
|
327
|
+
app(appId: string): {
|
|
328
|
+
data: Pick<AppDataHandle, 'get' | 'getData'>;
|
|
329
|
+
};
|
|
330
|
+
}
|
|
271
331
|
/** Identity of whoever invoked a server function. */
|
|
272
332
|
export interface ServerFunctionCaller {
|
|
273
333
|
/** Authenticated user id, or `null` for anonymous/public/system invocations. */
|
|
@@ -297,7 +357,7 @@ export interface ServerFunctionContext {
|
|
|
297
357
|
* only — never a global superuser.
|
|
298
358
|
* Declared `capabilities` cap what these calls may do.
|
|
299
359
|
*/
|
|
300
|
-
sl:
|
|
360
|
+
sl: ServerFunctionSl;
|
|
301
361
|
/**
|
|
302
362
|
* Capability-gated secret access (both require the `secrets:<ref>` capability).
|
|
303
363
|
* `get(ref)` resolves the collection's OWN secret first (a client's credential), then falls back
|
|
@@ -315,7 +375,29 @@ export interface ServerFunctionContext {
|
|
|
315
375
|
/** Structured logging captured into run telemetry. */
|
|
316
376
|
log: (message: string, data?: Record<string, any>) => void;
|
|
317
377
|
}
|
|
318
|
-
/** The
|
|
378
|
+
/** The HTTP request handed to an `http`-trigger function as `event`. */
|
|
379
|
+
export interface ServerFunctionHttpEvent<TBody = any> {
|
|
380
|
+
method: string;
|
|
381
|
+
/** Parsed JSON body (when the request was JSON). */
|
|
382
|
+
body: TBody;
|
|
383
|
+
query: Record<string, any>;
|
|
384
|
+
/** Raw request headers (lower-cased keys). */
|
|
385
|
+
headers: Record<string, any>;
|
|
386
|
+
/** Raw request body bytes, when captured — for non-JSON inputs (XML, form, …). */
|
|
387
|
+
rawBody?: string | Buffer | null;
|
|
388
|
+
/** The request `content-type`, if any. */
|
|
389
|
+
contentType?: string | null;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The signature every SmartLinks server function implements.
|
|
393
|
+
*
|
|
394
|
+
* RETURN CONTRACT (http trigger): whatever you return **is** the HTTP response.
|
|
395
|
+
* - a plain value → JSON body, HTTP 200 (no `{ ok, result }` envelope);
|
|
396
|
+
* - a web-standard `Response` → passed through verbatim (your status, headers, content-type, body —
|
|
397
|
+
* XML, CSV, binary, redirect, custom status);
|
|
398
|
+
* - throwing → HTTP 500 `{ error, message, code }`. For expected errors, return a `Response` with
|
|
399
|
+
* your own 4xx/5xx.
|
|
400
|
+
*/
|
|
319
401
|
export type ServerFunctionHandler<TEvent = any, TResult = any> = (ctx: ServerFunctionContext, event: TEvent) => Promise<TResult> | TResult;
|
|
320
402
|
/**
|
|
321
403
|
* Shape of `app.admin.json` -- the separate admin configuration file pointed to
|
|
@@ -403,6 +485,41 @@ export interface AppAdminConfig {
|
|
|
403
485
|
* Setup, import, tunable, and metrics configuration lives in a separate
|
|
404
486
|
* `app.admin.json` file. Use the `admin` field to locate and fetch it.
|
|
405
487
|
*/
|
|
488
|
+
/** A public view's kind: context-aware (tag-tap) vs a full-screen, non-contextual screen. */
|
|
489
|
+
export type PublicViewKind = 'contextual' | 'standalone';
|
|
490
|
+
/** The caller-supplied params a public view expects. */
|
|
491
|
+
export interface PublicViewParams {
|
|
492
|
+
/** Params the view REQUIRES to render (e.g. `['collectionId','pageId']`). */
|
|
493
|
+
required?: string[];
|
|
494
|
+
/** Params the view can use if present (e.g. `['productId','proofId','orientation']`). */
|
|
495
|
+
optional?: string[];
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* A declared PUBLIC VIEW of the app — one soft-routed entry over the single public bundle
|
|
499
|
+
* (`index.html` → HashRouter), so the platform + Dev Hub can enumerate and target it instead of
|
|
500
|
+
* guessing at undeclared hash routes. A view is `route` + fixed params (`set`) + caller `params` +
|
|
501
|
+
* a `kind`. It is a DELIVERY-agnostic description: the same view renders as a `page` (standalone
|
|
502
|
+
* HTML, hash-routed, its own CSS — embed in an iframe or open directly) or, for a `contextual` view,
|
|
503
|
+
* as a `component` (PublicContainer, props context). NOT a separate build. See
|
|
504
|
+
* docs/design/public-views.md. (Distinct from `linkable`/DeepLinkEntry, which is deep-link
|
|
505
|
+
* discovery; publicViews is the top-level public-entry taxonomy used for preview + tag-tap routing.)
|
|
506
|
+
*/
|
|
507
|
+
export interface PublicView {
|
|
508
|
+
/** Stable id, unique within the app. */
|
|
509
|
+
id: string;
|
|
510
|
+
/** Human label (Dev Hub dropdown, platform pickers). */
|
|
511
|
+
title: string;
|
|
512
|
+
/** `contextual` (context-aware, tag-tap target) or `standalone` (full-screen display/kiosk). */
|
|
513
|
+
kind: PublicViewKind;
|
|
514
|
+
/** Hash route within the public bundle. Defaults to `/`. */
|
|
515
|
+
route?: string;
|
|
516
|
+
/** Query params this view PINS (e.g. `{ tvMode: 'true' }`), merged under the caller's params. */
|
|
517
|
+
set?: Record<string, string>;
|
|
518
|
+
/** The params the caller supplies. */
|
|
519
|
+
params?: PublicViewParams;
|
|
520
|
+
/** The default `contextual` view — the tag-tap target. At most one view sets this. */
|
|
521
|
+
default?: boolean;
|
|
522
|
+
}
|
|
406
523
|
export interface AppManifest {
|
|
407
524
|
$schema?: string;
|
|
408
525
|
meta?: {
|
|
@@ -491,6 +608,14 @@ export interface AppManifest {
|
|
|
491
608
|
* @see DeepLinkEntry
|
|
492
609
|
*/
|
|
493
610
|
linkable?: DeepLinkEntry[];
|
|
611
|
+
/**
|
|
612
|
+
* The app's PUBLIC VIEWS — the soft-routed entries over the single public bundle
|
|
613
|
+
* (contextual page, display board, kiosk/TV, …), so the platform + Dev Hub can enumerate,
|
|
614
|
+
* preview, and target them. Declares `route` + fixed `set` params + caller `params` + `kind`
|
|
615
|
+
* per view; the `default` contextual view is the tag-tap target. See PublicView +
|
|
616
|
+
* docs/design/public-views.md.
|
|
617
|
+
*/
|
|
618
|
+
publicViews?: PublicView[];
|
|
494
619
|
/**
|
|
495
620
|
* Executor bundle declaration. Present when the app ships a programmatic executor
|
|
496
621
|
* for AI-driven configuration, server-side SEO, and LLM content generation.
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.24 | Generated: 2026-09-27T07:52:03.418Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -2132,6 +2132,7 @@ interface AppFunctionDef {
|
|
|
2132
2132
|
authority?: AppFunctionAuthority;
|
|
2133
2133
|
elevated?: boolean;
|
|
2134
2134
|
capabilities?: string[];
|
|
2135
|
+
dataScope?: 'collection' | 'global';
|
|
2135
2136
|
apiVersion?: string;
|
|
2136
2137
|
handler?: string;
|
|
2137
2138
|
}
|
|
@@ -2145,6 +2146,40 @@ interface AppManifestFunctions {
|
|
|
2145
2146
|
}
|
|
2146
2147
|
```
|
|
2147
2148
|
|
|
2149
|
+
**AppDataOpts** (interface)
|
|
2150
|
+
```typescript
|
|
2151
|
+
interface AppDataOpts {
|
|
2152
|
+
scope?: 'collection' | 'global';
|
|
2153
|
+
productId?: string;
|
|
2154
|
+
variantId?: string;
|
|
2155
|
+
batchId?: string;
|
|
2156
|
+
dataId?: string;
|
|
2157
|
+
queries?: Record<string, any>;
|
|
2158
|
+
}
|
|
2159
|
+
```
|
|
2160
|
+
|
|
2161
|
+
**AppDataHandle** (interface)
|
|
2162
|
+
```typescript
|
|
2163
|
+
interface AppDataHandle {
|
|
2164
|
+
get(opts?: AppDataOpts): Promise<any>;
|
|
2165
|
+
set(data: any, opts?: AppDataOpts): Promise<any>;
|
|
2166
|
+
getData(opts?: AppDataOpts): Promise<any>;
|
|
2167
|
+
setData(data: any, opts?: AppDataOpts): Promise<any>;
|
|
2168
|
+
delete(opts?: AppDataOpts): Promise<any>;
|
|
2169
|
+
}
|
|
2170
|
+
```
|
|
2171
|
+
|
|
2172
|
+
**ServerFunctionSl** (interface)
|
|
2173
|
+
```typescript
|
|
2174
|
+
interface ServerFunctionSl {
|
|
2175
|
+
appRecords: any;
|
|
2176
|
+
products: any;
|
|
2177
|
+
attestations: any;
|
|
2178
|
+
appData: AppDataHandle & { global: AppDataHandle; collection: AppDataHandle };
|
|
2179
|
+
app(appId: string): { data: Pick<AppDataHandle, 'get' | 'getData'> };
|
|
2180
|
+
}
|
|
2181
|
+
```
|
|
2182
|
+
|
|
2148
2183
|
**ServerFunctionCaller** (interface)
|
|
2149
2184
|
```typescript
|
|
2150
2185
|
interface ServerFunctionCaller {
|
|
@@ -2161,7 +2196,7 @@ interface ServerFunctionCaller {
|
|
|
2161
2196
|
interface ServerFunctionContext {
|
|
2162
2197
|
collectionId: string;
|
|
2163
2198
|
appId: string;
|
|
2164
|
-
sl:
|
|
2199
|
+
sl: ServerFunctionSl;
|
|
2165
2200
|
secrets: {
|
|
2166
2201
|
get(ref: string): Promise<string | null>;
|
|
2167
2202
|
app(ref: string): Promise<string | null>;
|
|
@@ -2172,6 +2207,18 @@ interface ServerFunctionContext {
|
|
|
2172
2207
|
}
|
|
2173
2208
|
```
|
|
2174
2209
|
|
|
2210
|
+
**ServerFunctionHttpEvent<TBody = any>** (interface)
|
|
2211
|
+
```typescript
|
|
2212
|
+
interface ServerFunctionHttpEvent<TBody = any> {
|
|
2213
|
+
method: string;
|
|
2214
|
+
body: TBody;
|
|
2215
|
+
query: Record<string, any>;
|
|
2216
|
+
headers: Record<string, any>;
|
|
2217
|
+
rawBody?: string | Buffer | null;
|
|
2218
|
+
contentType?: string | null;
|
|
2219
|
+
}
|
|
2220
|
+
```
|
|
2221
|
+
|
|
2175
2222
|
**AppAdminConfig** (interface)
|
|
2176
2223
|
```typescript
|
|
2177
2224
|
interface AppAdminConfig {
|
|
@@ -2233,6 +2280,27 @@ interface AppAdminConfig {
|
|
|
2233
2280
|
}
|
|
2234
2281
|
```
|
|
2235
2282
|
|
|
2283
|
+
**PublicViewParams** (interface)
|
|
2284
|
+
```typescript
|
|
2285
|
+
interface PublicViewParams {
|
|
2286
|
+
required?: string[];
|
|
2287
|
+
optional?: string[];
|
|
2288
|
+
}
|
|
2289
|
+
```
|
|
2290
|
+
|
|
2291
|
+
**PublicView** (interface)
|
|
2292
|
+
```typescript
|
|
2293
|
+
interface PublicView {
|
|
2294
|
+
id: string;
|
|
2295
|
+
title: string;
|
|
2296
|
+
kind: PublicViewKind;
|
|
2297
|
+
route?: string;
|
|
2298
|
+
set?: Record<string, string>;
|
|
2299
|
+
params?: PublicViewParams;
|
|
2300
|
+
default?: boolean;
|
|
2301
|
+
}
|
|
2302
|
+
```
|
|
2303
|
+
|
|
2236
2304
|
**AppManifest** (interface)
|
|
2237
2305
|
```typescript
|
|
2238
2306
|
interface AppManifest {
|
|
@@ -2267,6 +2335,7 @@ interface AppManifest {
|
|
|
2267
2335
|
components: AppContainerComponent[];
|
|
2268
2336
|
};
|
|
2269
2337
|
linkable?: DeepLinkEntry[];
|
|
2338
|
+
publicViews?: PublicView[];
|
|
2270
2339
|
executor?: AppManifestExecutor;
|
|
2271
2340
|
functions?: AppManifestFunctions;
|
|
2272
2341
|
[key: string]: any;
|
|
@@ -2304,6 +2373,8 @@ interface GetCollectionWidgetsOptions {
|
|
|
2304
2373
|
|
|
2305
2374
|
**AppFunctionAuthority** = `'caller' | 'collection'`
|
|
2306
2375
|
|
|
2376
|
+
**PublicViewKind** = `'contextual' | 'standalone'`
|
|
2377
|
+
|
|
2307
2378
|
### appObjects
|
|
2308
2379
|
|
|
2309
2380
|
**PaginatedResponse<T>** (interface)
|
|
@@ -8969,7 +9040,7 @@ interface FunctionListResponse {
|
|
|
8969
9040
|
**FunctionCallOptions** (interface)
|
|
8970
9041
|
```typescript
|
|
8971
9042
|
interface FunctionCallOptions {
|
|
8972
|
-
appId?: string
|
|
9043
|
+
appId?: string; channel?: string
|
|
8973
9044
|
}
|
|
8974
9045
|
```
|
|
8975
9046
|
|
package/docs/app-manifest.md
CHANGED
|
@@ -332,6 +332,40 @@ See the [Deep Link Discovery guide](deep-link-discovery.md) for the full dual-so
|
|
|
332
332
|
| `path` | string | ❌ | Hash route within the app (defaults to `"/"` if omitted) |
|
|
333
333
|
| `params` | object | ❌ | App-specific query params appended to the URL — do **not** include platform params (`collectionId`, `productId`, etc.) |
|
|
334
334
|
|
|
335
|
+
#### `publicViews`
|
|
336
|
+
|
|
337
|
+
Declares the app's **public views** — the soft-routed entries over your single public bundle
|
|
338
|
+
(`index.html` → HashRouter): the contextual page, a display board, a kiosk/TV screen, etc. Without
|
|
339
|
+
this, those routes/modes are invisible to the platform and the Dev Hub. Each view is a `route` + fixed
|
|
340
|
+
`set` params + caller `params` + a `kind`; the `default` **contextual** view is the tag-tap target.
|
|
341
|
+
It's delivery-agnostic — the same view renders as a **page** (standalone, self-CSS, hash-routed, embed
|
|
342
|
+
in an iframe or open directly) or, for a contextual view, as a **component** (`PublicContainer`).
|
|
343
|
+
Not a separate build. (Distinct from `linkable`, which is deep-link discovery.)
|
|
344
|
+
|
|
345
|
+
```json
|
|
346
|
+
"publicViews": [
|
|
347
|
+
{ "id": "page", "title": "Product page", "kind": "contextual", "route": "/", "default": true,
|
|
348
|
+
"params": { "required": ["collectionId"], "optional": ["productId", "proofId"] } },
|
|
349
|
+
{ "id": "board", "title": "Display board", "kind": "standalone", "route": "/preview",
|
|
350
|
+
"params": { "required": ["collectionId", "appId", "pageId"], "optional": ["orientation"] } },
|
|
351
|
+
{ "id": "tv", "title": "TV / big screen", "kind": "standalone", "route": "/",
|
|
352
|
+
"set": { "tvMode": "true" }, "params": { "required": ["collectionId", "voteId"] } }
|
|
353
|
+
]
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
| Field | Type | Required | Description |
|
|
357
|
+
|-------|------|----------|-------------|
|
|
358
|
+
| `id` | string | ✅ | Stable id, unique within the app |
|
|
359
|
+
| `title` | string | ✅ | Human label (Dev Hub dropdown, platform pickers) |
|
|
360
|
+
| `kind` | `"contextual"` \| `"standalone"` | ✅ | Context-aware (tag-tap) vs full-screen, non-contextual |
|
|
361
|
+
| `route` | string | ❌ | Hash route within the public bundle (defaults to `"/"`) |
|
|
362
|
+
| `set` | object | ❌ | Query params this view PINS (e.g. `{ "tvMode": "true" }`), merged under caller params |
|
|
363
|
+
| `params` | `{ required?: string[]; optional?: string[] }` | ❌ | The params the caller supplies |
|
|
364
|
+
| `default` | boolean | ❌ | The default contextual view — the tag-tap target (at most one) |
|
|
365
|
+
|
|
366
|
+
Read context the same way in every delivery with **`SL.readContext(props?)`** (merges props → hash →
|
|
367
|
+
search), instead of hand-rolling the `containerProps || hash || search` chain.
|
|
368
|
+
|
|
335
369
|
#### `records`
|
|
336
370
|
|
|
337
371
|
Declares which `app.records` record types the app stores, and which scopes each type supports. Required for any app that follows the [App Records Pattern](app-records-pattern.md). Omit if the app does not use scoped records.
|