@proveanything/smartlinks 2.0.21 → 2.0.22

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.
@@ -8,9 +8,16 @@ export interface FunctionListEntry {
8
8
  export interface FunctionListResponse {
9
9
  functions: FunctionListEntry[];
10
10
  }
11
- /** Options for a function call. `appId` scopes resolution to one app (recommended). */
11
+ /**
12
+ * Options for a function call.
13
+ * - `appId` scopes resolution to one app (recommended; falls back to the SDK app context).
14
+ * - `channel` selects which release to run when addressing an app that is NOT enabled on the
15
+ * collection (enablement isn't required — the app is resolved directly by id). Defaults to
16
+ * `stable` server-side, so pass `channel: 'dev'` to test a dev build before installing it.
17
+ */
12
18
  export interface FunctionCallOptions {
13
19
  appId?: string;
20
+ channel?: string;
14
21
  }
15
22
  export declare namespace functions {
16
23
  /**
@@ -14,13 +14,15 @@
14
14
  // which the server resolves by bare name and REJECTS with 409 AMBIGUOUS_FUNCTION when more than one
15
15
  // installed app defines that name. Always prefer an appId.
16
16
  import { post, request, getAppContext } from "../http.js";
17
- function fnPath(surface, collectionId, name, appId) {
17
+ function fnPath(surface, collectionId, name, opts = {}) {
18
+ var _a;
18
19
  const c = encodeURIComponent(collectionId);
19
20
  const n = encodeURIComponent(name);
20
- const app = appId !== null && appId !== void 0 ? appId : getAppContext();
21
+ const app = (_a = opts.appId) !== null && _a !== void 0 ? _a : getAppContext();
22
+ const q = opts.channel ? `?channel=${encodeURIComponent(opts.channel)}` : '';
21
23
  return app
22
- ? `/${surface}/collection/${c}/app/${encodeURIComponent(app)}/functions/${n}`
23
- : `/${surface}/collection/${c}/functions/${n}`; // deprecated flat alias
24
+ ? `/${surface}/collection/${c}/app/${encodeURIComponent(app)}/functions/${n}${q}`
25
+ : `/${surface}/collection/${c}/functions/${n}${q}`; // deprecated flat alias
24
26
  }
25
27
  export var functions;
26
28
  (function (functions) {
@@ -35,7 +37,7 @@ export var functions;
35
37
  * await SL.functions.call(collectionId, 'pressCounter', {}, { appId: 'my-counter-app' })
36
38
  */
37
39
  async function call(collectionId, name, body = {}, opts = {}) {
38
- return post(fnPath('public', collectionId, name, opts.appId), body);
40
+ return post(fnPath('public', collectionId, name, opts), body);
39
41
  }
40
42
  functions.call = call;
41
43
  /**
@@ -43,7 +45,7 @@ export var functions;
43
45
  * App-scoped: `POST /admin/collection/:c/app/:appId/functions/:name`.
44
46
  */
45
47
  async function callAdmin(collectionId, name, body = {}, opts = {}) {
46
- return post(fnPath('admin', collectionId, name, opts.appId), body);
48
+ return post(fnPath('admin', collectionId, name, opts), body);
47
49
  }
48
50
  functions.callAdmin = callAdmin;
49
51
  /**
@@ -54,9 +56,10 @@ export var functions;
54
56
  var _a;
55
57
  const c = encodeURIComponent(collectionId);
56
58
  const app = (_a = opts.appId) !== null && _a !== void 0 ? _a : getAppContext();
59
+ const q = opts.channel ? `?channel=${encodeURIComponent(opts.channel)}` : '';
57
60
  const path = app
58
- ? `/public/collection/${c}/app/${encodeURIComponent(app)}/functions`
59
- : `/public/collection/${c}/functions`;
61
+ ? `/public/collection/${c}/app/${encodeURIComponent(app)}/functions${q}`
62
+ : `/public/collection/${c}/functions${q}`;
60
63
  return request(path);
61
64
  }
62
65
  functions.list = list;
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.0.21 | Generated: 2026-09-25T17:47:14.766Z
3
+ Version: 2.0.22 | Generated: 2026-09-25T18:07:22.478Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -8969,7 +8969,7 @@ interface FunctionListResponse {
8969
8969
  **FunctionCallOptions** (interface)
8970
8970
  ```typescript
8971
8971
  interface FunctionCallOptions {
8972
- appId?: string
8972
+ appId?: string; channel?: string
8973
8973
  }
8974
8974
  ```
8975
8975
 
@@ -248,10 +248,21 @@ To call a *different* app's function, pass the appId explicitly:
248
248
  await SL.functions.call(collectionId, 'pressCounter', {}, { appId: 'some-other-app' })
249
249
  ```
250
250
 
251
+ **The app does NOT have to be enabled on the collection.** Because the appId is explicit, the
252
+ function is resolved directly from the app's release — so you can test an app on any collection
253
+ before installing it (and without it showing up in that collection's menus). Enabling an app is
254
+ currently just a UX courtesy (dropdowns/menus), not a gate on running its functions. For a build
255
+ that isn't the default `stable` channel — e.g. a **dev** app you haven't installed — pass the
256
+ channel:
257
+
258
+ ```ts
259
+ await SL.functions.call(collectionId, 'pressCounter', {}, { appId: 'my-counter-app', channel: 'dev' })
260
+ ```
261
+
251
262
  If no appId is available (not set on init, none passed), the call falls back to the **deprecated
252
- flat path** `/collection/:c/functions/:name`, which the server resolves by bare name and **rejects
253
- with `409 AMBIGUOUS_FUNCTION`** when more than one installed app defines that name (a first-party
254
- builtin still wins). Always prefer an appId.
263
+ flat path** `/collection/:c/functions/:name`, which searches only the collection's **enabled** apps,
264
+ resolves by bare name, and **rejects with `409 AMBIGUOUS_FUNCTION`** when more than one defines that
265
+ name (a first-party builtin still wins). Always prefer an appId.
255
266
 
256
267
  > There is no such thing as an app-less function. First-party builtins (e.g. the `functions.ping`
257
268
  > diagnostic) belong to the reserved `smartlinks` app. A "global" function is just an app enabled on
@@ -376,10 +387,21 @@ POST /public/collection/:collectionId/app/:appId/functions/:name # visibility:
376
387
  GET /{admin|public}/collection/:collectionId/app/:appId/functions # list this app's functions on the surface
377
388
  ```
378
389
 
390
+ The app-scoped route resolves the app **directly by id**, so the app need not be enabled on the
391
+ collection — handy for testing an un-installed (dev) app. Add `?channel=dev` (default `stable`) to
392
+ pick the release. Enablement (`appConfig.apps[]`) currently only controls menus/discovery, not
393
+ whether a function can run.
394
+
379
395
  The bare-name form (`/collection/:c/functions/:name`, no `/app/:appId`) is a **deprecated alias**:
380
- it resolves by name across all installed apps, lets a first-party builtin win, and returns
381
- `409 AMBIGUOUS_FUNCTION` when two apps define the same name. Prefer the app-scoped route (the SDK
382
- emits it automatically once an appId is set — see "Calling a function from your app").
396
+ it searches only the collection's **enabled** apps, resolves by name, lets a first-party builtin
397
+ win, and returns `409 AMBIGUOUS_FUNCTION` when two enabled apps define the same name. Prefer the
398
+ app-scoped route (the SDK emits it automatically once an appId is set — see "Calling a function
399
+ from your app").
400
+
401
+ > **Security note (first-party model, today):** because enablement is not an auth gate, any app's
402
+ > function can be invoked on any collection by id. That's fine while all apps are first-party and
403
+ > trusted. When untrusted third-party apps arrive, gate *elevated* (`public` + `collection`)
404
+ > invocation of a **non-enabled** app behind install/consent — the app-scoped resolver is the seam.
383
405
 
384
406
  The request body is delivered to the handler as `event.body` (query string as
385
407
  `event.query`). A function only runs on its own surface — calling an `admin` function on
package/dist/openapi.yaml CHANGED
@@ -29290,7 +29290,8 @@ components:
29290
29290
  type: object
29291
29291
  properties:
29292
29292
  appId:
29293
- type: string
29293
+ type: object
29294
+ additionalProperties: true
29294
29295
  AllocateSequenceInput:
29295
29296
  type: object
29296
29297
  properties:
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.0.21 | Generated: 2026-09-25T17:47:14.766Z
3
+ Version: 2.0.22 | Generated: 2026-09-25T18:07:22.478Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -8969,7 +8969,7 @@ interface FunctionListResponse {
8969
8969
  **FunctionCallOptions** (interface)
8970
8970
  ```typescript
8971
8971
  interface FunctionCallOptions {
8972
- appId?: string
8972
+ appId?: string; channel?: string
8973
8973
  }
8974
8974
  ```
8975
8975
 
@@ -248,10 +248,21 @@ To call a *different* app's function, pass the appId explicitly:
248
248
  await SL.functions.call(collectionId, 'pressCounter', {}, { appId: 'some-other-app' })
249
249
  ```
250
250
 
251
+ **The app does NOT have to be enabled on the collection.** Because the appId is explicit, the
252
+ function is resolved directly from the app's release — so you can test an app on any collection
253
+ before installing it (and without it showing up in that collection's menus). Enabling an app is
254
+ currently just a UX courtesy (dropdowns/menus), not a gate on running its functions. For a build
255
+ that isn't the default `stable` channel — e.g. a **dev** app you haven't installed — pass the
256
+ channel:
257
+
258
+ ```ts
259
+ await SL.functions.call(collectionId, 'pressCounter', {}, { appId: 'my-counter-app', channel: 'dev' })
260
+ ```
261
+
251
262
  If no appId is available (not set on init, none passed), the call falls back to the **deprecated
252
- flat path** `/collection/:c/functions/:name`, which the server resolves by bare name and **rejects
253
- with `409 AMBIGUOUS_FUNCTION`** when more than one installed app defines that name (a first-party
254
- builtin still wins). Always prefer an appId.
263
+ flat path** `/collection/:c/functions/:name`, which searches only the collection's **enabled** apps,
264
+ resolves by bare name, and **rejects with `409 AMBIGUOUS_FUNCTION`** when more than one defines that
265
+ name (a first-party builtin still wins). Always prefer an appId.
255
266
 
256
267
  > There is no such thing as an app-less function. First-party builtins (e.g. the `functions.ping`
257
268
  > diagnostic) belong to the reserved `smartlinks` app. A "global" function is just an app enabled on
@@ -376,10 +387,21 @@ POST /public/collection/:collectionId/app/:appId/functions/:name # visibility:
376
387
  GET /{admin|public}/collection/:collectionId/app/:appId/functions # list this app's functions on the surface
377
388
  ```
378
389
 
390
+ The app-scoped route resolves the app **directly by id**, so the app need not be enabled on the
391
+ collection — handy for testing an un-installed (dev) app. Add `?channel=dev` (default `stable`) to
392
+ pick the release. Enablement (`appConfig.apps[]`) currently only controls menus/discovery, not
393
+ whether a function can run.
394
+
379
395
  The bare-name form (`/collection/:c/functions/:name`, no `/app/:appId`) is a **deprecated alias**:
380
- it resolves by name across all installed apps, lets a first-party builtin win, and returns
381
- `409 AMBIGUOUS_FUNCTION` when two apps define the same name. Prefer the app-scoped route (the SDK
382
- emits it automatically once an appId is set — see "Calling a function from your app").
396
+ it searches only the collection's **enabled** apps, resolves by name, lets a first-party builtin
397
+ win, and returns `409 AMBIGUOUS_FUNCTION` when two enabled apps define the same name. Prefer the
398
+ app-scoped route (the SDK emits it automatically once an appId is set — see "Calling a function
399
+ from your app").
400
+
401
+ > **Security note (first-party model, today):** because enablement is not an auth gate, any app's
402
+ > function can be invoked on any collection by id. That's fine while all apps are first-party and
403
+ > trusted. When untrusted third-party apps arrive, gate *elevated* (`public` + `collection`)
404
+ > invocation of a **non-enabled** app behind install/consent — the app-scoped resolver is the seam.
383
405
 
384
406
  The request body is delivered to the handler as `event.body` (query string as
385
407
  `event.query`). A function only runs on its own surface — calling an `admin` function on
package/openapi.yaml CHANGED
@@ -29290,7 +29290,8 @@ components:
29290
29290
  type: object
29291
29291
  properties:
29292
29292
  appId:
29293
- type: string
29293
+ type: object
29294
+ additionalProperties: true
29294
29295
  AllocateSequenceInput:
29295
29296
  type: object
29296
29297
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "2.0.21",
3
+ "version": "2.0.22",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",