viasocket-apps 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -88,9 +88,9 @@ const subscription = await user.subscribe(triggerVersionId, {
88
88
  import { connect } from 'viasocket-apps/browser'
89
89
 
90
90
  // embedToken comes from your backend (user.token()), signed for the signed-in user.
91
- // actions (optional): the rowids of the actions and triggers you use — the popup then asks only
91
+ // actions (optional): the action_ids and trigger_ids you use — the popup then asks only
92
92
  // for their scopes; skipActionSelection goes straight to the app's consent screen.
93
- const { authId } = await connect({ embedToken, serviceId: 'rowbu58rc', actions: ['<action rowid>'], skipActionSelection: true })
93
+ const { authId } = await connect({ embedToken, serviceId: 'rowbu58rc', actions: ['<action_id>'], skipActionSelection: true })
94
94
  // Send authId to your backend, which enables the app and stores the script_id.
95
95
  ```
96
96
 
@@ -108,8 +108,8 @@ const { authId } = await connect({ embedToken, serviceId: 'rowbu58rc', actions:
108
108
  | `user.listOptions(actionVersionId, { fieldKey, authId, existingFields })` | The values a field accepts, as `{ options, offset }`. Both response shapes normalised; an unreadable connection (revoked, another user's `auth_id`) throws a `ViaSocketError` with status 400 even though the API answers 200. |
109
109
  | `viasocket.runAction(scriptId, actionVersionId, inputData)` | Run one action. Returns the app's own response. |
110
110
  | `viasocket.catalog.search(key)` | The best 30 apps for what the user typed, as `{ serviceId, name, iconUrl, description }`. No token. |
111
- | `viasocket.catalog.list({ limit, offset, category })` | Every app, most used first, 200 a page; an empty page ends it. Drop apps whose `versions()` is empty. No token. |
112
- | `viasocket.catalog.versions(serviceId)` | Every published action and trigger of one app, as `{ actions, triggers }`, each with its `inputjson` schema and version id. No token. |
111
+ | `viasocket.catalog.list({ limit, offset, category })` | Every app, most used first, 200 a page; an empty page ends it. Drop apps whose `versions()` is `null` or empty. No token. |
112
+ | `viasocket.catalog.versions(serviceId)` | One app and every published action and trigger of it, as `{ service, actions, triggers }`. Each action has `action_id` and `action_version_id`, each trigger `trigger_id` and `trigger_version_id`, named as the calls take them: the version id for `runAction`, `listOptions` and `subscribe`; the other for `connect`, automations and the prebuilt UI. `input_schema` is the form schema. `null` for an unknown id. No token. |
113
113
  | `user.subscribe(triggerVersionId, { authId, inputData, code \| webhook, meta })` | Subscribe to an app event with a handler we run per event. Returns `{ scriptId, hookUrl, … }`. |
114
114
  | `user.updateSubscription(scriptId, { code, meta })` | Change a live subscription in place. |
115
115
 
@@ -19,7 +19,7 @@ const DEFAULT_RUN_BASE_URL = 'https://flow.sokt.io';
19
19
  const CATALOG = {
20
20
  search: 'https://flow.sokt.io/func/scri12BSufQM',
21
21
  list: 'https://plug-service.viasocket.com/api/v1/plugins/all',
22
- versions: 'https://flow.sokt.io/func/scriolZue69X'
22
+ versions: 'https://flow.sokt.io/func/scriK4LFg2kc'
23
23
  };
24
24
  const LIST_LIMIT_MAX = 200;
25
25
  function required(name, value) {
@@ -95,9 +95,13 @@ class ViaSocket {
95
95
  }));
96
96
  },
97
97
  /**
98
- * Every published action and trigger of one app, with the schema (`inputjson`) a form is
99
- * rendered from and the version id the run and subscribe calls take. Empty for an app with
100
- * nothing published. Cache it per app; ids are stable and schemas change rarely.
98
+ * One app and every published action and trigger of it, as `{ service, actions, triggers }`.
99
+ * Each action carries `action_id` and `action_version_id`, each trigger `trigger_id` and
100
+ * `trigger_version_id` — named as the calls take them: the version id for `runAction`,
101
+ * `listOptions` and `subscribe`; the other for `connect`, automations and the prebuilt UI.
102
+ * `input_schema` is the field schema a form is rendered from. `null` for an unknown service id
103
+ * (the API answers 200 with an empty service); empty arrays for an app with nothing published.
104
+ * Cache it per app; ids are stable and schemas change rarely.
101
105
  */
102
106
  versions: async (serviceId) => {
103
107
  const { data } = await (0, http_js_1.request)({
@@ -106,8 +110,16 @@ class ViaSocket {
106
110
  body: JSON.stringify({ service_id: required('serviceId', serviceId) }),
107
111
  fetchImpl: this.transport
108
112
  });
109
- const rows = Array.isArray(data) ? data : [];
110
- return { actions: rows.filter((row) => row.type === 'action'), triggers: rows.filter((row) => row.type === 'trigger') };
113
+ // No `success` key, so the body arrives whole as `data`; tolerate an envelope anyway.
114
+ const body = (data && 'service' in data ? data : data?.data) ?? {};
115
+ const service = body.service;
116
+ if (!service?.name)
117
+ return null;
118
+ return {
119
+ service,
120
+ actions: Array.isArray(body.actions) ? body.actions : [],
121
+ triggers: Array.isArray(body.triggers) ? body.triggers : []
122
+ };
111
123
  }
112
124
  };
113
125
  /** Everything that is done for one of your end users. */
@@ -28,8 +28,9 @@ export interface ConnectOptions {
28
28
  /** The app to connect. Its service_id is shown on every app in the Apps API reference. */
29
29
  serviceId: string;
30
30
  /**
31
- * The rowids of the actions and triggers this product uses (each is listed with its action in
32
- * the app's document). The popup then asks only for their scopes. Omit to offer every action.
31
+ * The `action_id`s and `trigger_id`s this product uses (listed under each one in the app's
32
+ * document and in `catalog.versions()`). The popup then asks only for their scopes. Omit to
33
+ * offer every action. Never a version id.
33
34
  */
34
35
  actions?: string[];
35
36
  /** With `actions`: skip the action list and open the app's consent screen directly. */
@@ -29,11 +29,15 @@ export declare class ViaSocket {
29
29
  */
30
30
  list: (params?: ListAppsParams) => Promise<CatalogApp[]>;
31
31
  /**
32
- * Every published action and trigger of one app, with the schema (`inputjson`) a form is
33
- * rendered from and the version id the run and subscribe calls take. Empty for an app with
34
- * nothing published. Cache it per app; ids are stable and schemas change rarely.
32
+ * One app and every published action and trigger of it, as `{ service, actions, triggers }`.
33
+ * Each action carries `action_id` and `action_version_id`, each trigger `trigger_id` and
34
+ * `trigger_version_id` — named as the calls take them: the version id for `runAction`,
35
+ * `listOptions` and `subscribe`; the other for `connect`, automations and the prebuilt UI.
36
+ * `input_schema` is the field schema a form is rendered from. `null` for an unknown service id
37
+ * (the API answers 200 with an empty service); empty arrays for an app with nothing published.
38
+ * Cache it per app; ids are stable and schemas change rarely.
35
39
  */
36
- versions: (serviceId: string) => Promise<CatalogVersions>;
40
+ versions: (serviceId: string) => Promise<CatalogVersions | null>;
37
41
  };
38
42
  /** Everything that is done for one of your end users. */
39
43
  user(uniqueIdentifier: string): UserScope;
@@ -16,7 +16,7 @@ const DEFAULT_RUN_BASE_URL = 'https://flow.sokt.io';
16
16
  const CATALOG = {
17
17
  search: 'https://flow.sokt.io/func/scri12BSufQM',
18
18
  list: 'https://plug-service.viasocket.com/api/v1/plugins/all',
19
- versions: 'https://flow.sokt.io/func/scriolZue69X'
19
+ versions: 'https://flow.sokt.io/func/scriK4LFg2kc'
20
20
  };
21
21
  const LIST_LIMIT_MAX = 200;
22
22
  function required(name, value) {
@@ -92,9 +92,13 @@ export class ViaSocket {
92
92
  }));
93
93
  },
94
94
  /**
95
- * Every published action and trigger of one app, with the schema (`inputjson`) a form is
96
- * rendered from and the version id the run and subscribe calls take. Empty for an app with
97
- * nothing published. Cache it per app; ids are stable and schemas change rarely.
95
+ * One app and every published action and trigger of it, as `{ service, actions, triggers }`.
96
+ * Each action carries `action_id` and `action_version_id`, each trigger `trigger_id` and
97
+ * `trigger_version_id` — named as the calls take them: the version id for `runAction`,
98
+ * `listOptions` and `subscribe`; the other for `connect`, automations and the prebuilt UI.
99
+ * `input_schema` is the field schema a form is rendered from. `null` for an unknown service id
100
+ * (the API answers 200 with an empty service); empty arrays for an app with nothing published.
101
+ * Cache it per app; ids are stable and schemas change rarely.
98
102
  */
99
103
  versions: async (serviceId) => {
100
104
  const { data } = await request({
@@ -103,8 +107,16 @@ export class ViaSocket {
103
107
  body: JSON.stringify({ service_id: required('serviceId', serviceId) }),
104
108
  fetchImpl: this.transport
105
109
  });
106
- const rows = Array.isArray(data) ? data : [];
107
- return { actions: rows.filter((row) => row.type === 'action'), triggers: rows.filter((row) => row.type === 'trigger') };
110
+ // No `success` key, so the body arrives whole as `data`; tolerate an envelope anyway.
111
+ const body = (data && 'service' in data ? data : data?.data) ?? {};
112
+ const service = body.service;
113
+ if (!service?.name)
114
+ return null;
115
+ return {
116
+ service,
117
+ actions: Array.isArray(body.actions) ? body.actions : [],
118
+ triggers: Array.isArray(body.triggers) ? body.triggers : []
119
+ };
108
120
  }
109
121
  };
110
122
  /** Everything that is done for one of your end users. */
@@ -18,4 +18,4 @@ export { ViaSocket, UserScope } from './client.js';
18
18
  export { ViaSocketError } from './errors.js';
19
19
  export { signEmbedToken } from './token.js';
20
20
  export type { SignEmbedTokenInput } from './token.js';
21
- export type { CatalogApp, CatalogVersion, CatalogVersions, EnableResult, Envelope, Flow, FlowStatus, ListAppsParams, ListOptionsParams, ListOptionsResult, Option, SubscribeParams, SubscribeResult, UpdateSubscriptionParams, ViaSocketOptions } from './types.js';
21
+ export type { CatalogApp, CatalogAction, CatalogService, CatalogTrigger, CatalogVersion, CatalogVersions, EnableResult, Envelope, Flow, FlowStatus, ListAppsParams, ListOptionsParams, ListOptionsResult, Option, SubscribeParams, SubscribeResult, UpdateSubscriptionParams, ViaSocketOptions } from './types.js';
@@ -116,24 +116,60 @@ export interface ListAppsParams {
116
116
  /** One of the catalog's category names, e.g. "CRM". */
117
117
  category?: string;
118
118
  }
119
- /** One published action or trigger version of an app, as the catalog returns it. */
120
- export interface CatalogVersion {
121
- /** The `action_version_id` (or trigger version id) the run and subscribe calls take. */
122
- actionversionrecordid: string;
123
- type: 'action' | 'trigger' | string;
119
+ /** The app, once, at the top of `catalog.versions()`. */
120
+ export interface CatalogService {
121
+ service_id: string;
122
+ /** The display name. The API sends `null` for an unknown id; `versions()` then returns `null` instead of a catalog. */
123
+ name: string;
124
+ description: string | null;
125
+ icon_url: string | null;
126
+ /** `Auth2.0`, `apikey`, `NoAuth`, … Informational: connect handles it. */
127
+ auth_type: string | null;
128
+ /** `false` for an app without sign-in: no connect button, and `'NoAuth'` wherever a call takes an `authId`. */
129
+ requires_auth: boolean;
130
+ }
131
+ interface CatalogEventBase {
124
132
  name: string;
125
133
  description: string;
126
- /** The field schema a form is rendered from; `inputData` follows it. */
127
- inputjson: Record<string, unknown>;
128
- sampledata?: unknown;
129
- pluginrecordid?: string;
130
- iconurl?: string;
131
- authtype?: string;
134
+ /**
135
+ * The field schema a form is rendered from; `inputData` follows it. A block with a `source` or
136
+ * `optionsGenerator` key is a picker: fill it with `listOptions`, never by running what the key holds.
137
+ */
138
+ input_schema: Record<string, unknown>;
139
+ /** A real response of the action, or a real event payload of the trigger. */
140
+ sample_output?: unknown;
141
+ updated_at?: string;
132
142
  [key: string]: unknown;
133
143
  }
144
+ /** One published action, its two ids named as the calls take them. */
145
+ export interface CatalogAction extends CatalogEventBase {
146
+ /**
147
+ * The action’s own id: what `connect`’s `actions`, an automation step’s `action_id` and the
148
+ * prebuilt UI’s `open: { actionId }` take. Looks like the version id and is not interchangeable with it.
149
+ */
150
+ action_id: string;
151
+ /** What `runAction` and `listOptions` take — and only those. */
152
+ action_version_id: string;
153
+ }
154
+ /** One published trigger, its two ids named as the calls take them. */
155
+ export interface CatalogTrigger extends CatalogEventBase {
156
+ /**
157
+ * The trigger’s own id: what `connect`’s `actions`, an automation’s `trigger_id` and the prebuilt
158
+ * UI’s `open: { triggerId }` take. Looks like the version id and is not interchangeable with it.
159
+ */
160
+ trigger_id: string;
161
+ /** What `subscribe` and `listOptions` take — and only those. */
162
+ trigger_version_id: string;
163
+ /** Not reliable yet: the API answers `true` for every trigger. */
164
+ polled?: boolean | null;
165
+ }
166
+ /** @deprecated The catalog no longer returns rows of one shape; use `CatalogAction` and `CatalogTrigger`. */
167
+ export type CatalogVersion = CatalogAction | CatalogTrigger;
168
+ /** What `catalog.versions()` returns for a known app. */
134
169
  export interface CatalogVersions {
135
- actions: CatalogVersion[];
136
- triggers: CatalogVersion[];
170
+ service: CatalogService;
171
+ actions: CatalogAction[];
172
+ triggers: CatalogTrigger[];
137
173
  }
138
174
  export interface Envelope<T = unknown> {
139
175
  success: boolean;
@@ -141,3 +177,4 @@ export interface Envelope<T = unknown> {
141
177
  data: T;
142
178
  isCached?: boolean;
143
179
  }
180
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viasocket-apps",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Server-side client for the viaSocket Apps API: let your users connect Slack, GitHub, Google Sheets or any of 2,300+ apps from your own product, then run actions and receive events through one API.",
5
5
  "keywords": [
6
6
  "viasocket",