@assembly-js/app-foundation 0.0.17 → 0.0.18
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/nango.d.ts +1 -1
- package/package.json +1 -1
- package/skills/assembly-integrations/providers/airtable.md +1 -0
- package/skills/assembly-integrations/providers/google-calendar.md +2 -0
- package/skills/assembly-integrations/providers/google-sheet.md +5 -1
- package/skills/assembly-integrations/providers/slack.md +2 -1
package/dist/nango.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ResourceFieldMap, type ResourcePage } from './resource-resolution.js';
|
|
2
|
-
export type Provider = 'slack' | '
|
|
2
|
+
export type Provider = 'slack' | 'gmail' | 'google-calendar' | 'google-drive' | 'google-sheet' | 'hubspot' | 'stripe' | 'airtable' | 'dropbox' | 'calendly' | 'clickup' | 'docusign' | 'quickbooks' | 'xero' | 'twilio' | 'zoom';
|
|
3
3
|
export type ConnectorErrorCode = 'app_key_required' | 'provider_not_declared' | 'connection_required' | 'needs_reauth' | 'needs_reauth_scope' | 'connection_throttled' | 'connector_unavailable' | 'action_failed' | 'invalid_request';
|
|
4
4
|
export interface ConnectionStatus {
|
|
5
5
|
provider: string;
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
- **Pagination:** `list-bases` takes `cursor` and returns `nextOffset`. `list-records` takes `offset` and returns `offset`. Passing the wrong key silently drops the next page.
|
|
9
9
|
- **`fields` is overloaded:** on `list-records` it is an array of field names to return; on `create-record` / `update-record` it is a name-or-id-keyed map of values to write. An array on a write, or a map on a read, is rejected.
|
|
10
10
|
- Resolve `baseId` with `list-bases` and table/field names with `get-base-schema` before writes. `tableIdOrName` accepts either; schema field ids survive a user renaming the column.
|
|
11
|
+
- **`delete-record` is permanent.** It returns `{ id, deleted }` and there is no undo through the API — a deleted record is only recoverable from Airtable's own trash by a human. Confirm destructive intent in the UI before calling it, and never wire it to a bulk action that runs without review.
|
|
11
12
|
|
|
12
13
|
```typescript
|
|
13
14
|
import { getIntegration, getAirtableTableSchema, formatAirtableRecords } from '@assembly-js/app-foundation/server';
|
|
@@ -6,6 +6,8 @@ Event `start` and `end` are objects, not strings: `{ dateTime: "2026-08-27T14:00
|
|
|
6
6
|
|
|
7
7
|
`attendees` is `[{ email }]`. Creating or updating with attendees does **not** email them unless `sendUpdates: "all"` is passed on `update-event` (create sends per Google defaults) — surface this as an explicit choice in the UI, not a surprise.
|
|
8
8
|
|
|
9
|
+
`get-event` fetches one event by id and returns the same item shape `list-events` does — use it instead of listing and filtering client-side. Cancelled events still return (with `status: "cancelled"`) rather than 404ing, so check `status` before rendering. For a recurring series, the id of an expanded instance (from `singleEvents: true`) and the id of the recurring master are different events; `get-event` returns whichever you ask for.
|
|
10
|
+
|
|
9
11
|
For listing over a window pass `timeMin`/`timeMax` (RFC3339) and `singleEvents: true` so recurring events expand into instances — without it you get the recurring master only, which renders as one event instead of many. `recurrence` on create takes RRULE strings, e.g. `["RRULE:FREQ=WEEKLY;BYDAY=MO"]`.
|
|
10
12
|
|
|
11
13
|
<!-- ASSEMBLY_ACTIONS:google-calendar -->
|
|
@@ -9,7 +9,11 @@ When `google-drive` is on the supported-provider list, declare it too and resolv
|
|
|
9
9
|
const id = url.match(/\/spreadsheets\/d\/([a-zA-Z0-9-_]+)/)?.[1];
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Then call `get-spreadsheet` with that id before doing anything else with it. It returns `spreadsheetTitle` and `sheets[]` (one entry per tab, `{ sheetId, title, index }`) and no cell data, so it is cheap. Two things fall out of it: a pasted id that is wrong or not shared with the connected account fails here, at paste time, instead of halfway through a write; and `sheets[]` is the tab list, so present a picker over its `title`s rather than asking the user to type a sheet name blind. The workbook's own name is `spreadsheetTitle` — it is a heading, never a tab option.
|
|
13
|
+
|
|
14
|
+
Ranges are A1 notation (`Sheet1!A1:D10`; quote sheet names with spaces: `'Q3 Data'!A:D`); `values` is a 2D array of rows — one inner array per row, cells as strings/numbers, never objects. A bare tab title is itself a valid range covering the whole tab, so a picked `title` can go straight into `range`, optionally with a cell span appended. `get-values` reads, `append-values-to-spreadsheet` appends to the table found in the range, `update-values` overwrites an exact range, `clear-values` empties one.
|
|
15
|
+
|
|
16
|
+
`clear-values` clears **values only**. Formatting, data validation, conditional formatting, notes, and the cells themselves all survive — the range is left blank, not deleted, so rows below do not shift up. There is no vendored way to delete rows or columns outright; that needs `spreadsheets.batchUpdate` through the proxy.
|
|
13
17
|
|
|
14
18
|
Writes take `valueInputOption`: `RAW` stores values verbatim; `USER_ENTERED` parses them as if typed in the UI (strings that look like numbers/dates convert, `=SUM(...)` becomes a formula). Default to `USER_ENTERED` for user-facing data entry and `RAW` when round-tripping values the app will read back.
|
|
15
19
|
|
|
@@ -4,7 +4,7 @@ Writes need membership, not just visibility. `send-message` reaches public chann
|
|
|
4
4
|
|
|
5
5
|
- **Post with `slackPostMessage` from `@assembly-js/app-foundation/server` — never hand-roll `chat.postMessage`.** It resolves a `#name` to the channel ID, posts, and on `not_in_channel` joins the channel and retries once. Slack-level failures come back as `{ ok: false, error }`; on `not_in_channel` render "invite the bot to #channel in Slack" (private channels cannot be self-joined).
|
|
6
6
|
- **Resolve channel names with `slackFindChannelId` from `@assembly-js/app-foundation/server` for every other per-channel call.** It handles cursor pagination (a single `conversations.list` misses channels in large workspaces), name normalization, scope fallback, rate limits, and caching. Use the returned ID; most Slack methods reject a `#name` with `invalid_arguments`.
|
|
7
|
-
- **Other writes (reactions,
|
|
7
|
+
- **Other writes (reactions, invites):** on `not_in_channel`, call `join-channel` with the channel ID, then retry once. Private channels fail `method_not_supported_for_channel_type` — tell the user to invite the bot instead of retrying.
|
|
8
8
|
- **Scopes:** `chat:write.public` lets posting reach any public channel without joining, so only the other writes need `join-channel`. Add `groups:read` if the app must find private channels.
|
|
9
9
|
|
|
10
10
|
```typescript
|
|
@@ -24,6 +24,7 @@ const history = await slack.action('get-conversation-history', {
|
|
|
24
24
|
|
|
25
25
|
For an operation no action covers, relay through the proxy — e.g. `slack.post({ endpoint: '/chat.update', data: { channel: channelId, ts, text } })`.
|
|
26
26
|
|
|
27
|
+
- **File uploads are not supported.** No upload action is vendored, and Slack's upload flow needs a multipart POST to the non-Slack URL `files.getUploadURLExternal` hands back, which the proxy cannot reach. Post a link to the file instead.
|
|
27
28
|
- **DMs are not supported.** The integration does not grant `im:write`, and `conversations.open` is not vendored. A Slack user ID (`U…`) or DM channel ID (`D…`) also fails `slackPostMessage`'s channel-ID check, so it falls through to a channel-name lookup and returns `channel_not_found` instead of opening the DM. If a user asks for DMs, say so up front and offer `createNotification` (in-product + email) or posting to a channel instead.
|
|
28
29
|
|
|
29
30
|
<!-- ASSEMBLY_ACTIONS:slack -->
|