@assembly-js/app-foundation 0.0.41 → 0.0.43
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/CHANGELOG.md +172 -0
- package/CLAUDE.md +279 -23
- package/bin/check-paint-beacon.mjs +8 -9
- package/bin/check-proxy-csrf.mjs +387 -0
- package/dist/proxy.d.ts +11 -0
- package/dist/proxy.js +669 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/fixes.json +64 -0
- package/package.json +5 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@assembly-js/app-foundation`, newest first. Each `## <version>` section
|
|
4
|
+
lists what that version means for an app that already exists, one kind per bullet:
|
|
5
|
+
|
|
6
|
+
- `[fix]` — fixed on install; the app's code doesn't change.
|
|
7
|
+
- `[behavior]` — the app behaves differently on install with no code change; its owner should know.
|
|
8
|
+
- `[action: <id>]` — the app's own code must change; `<id>` names the `fixes.json` entry that
|
|
9
|
+
detects the gap and tells the update agent how to close it.
|
|
10
|
+
- `[new]` — something the app can adopt; nothing changes until it does.
|
|
11
|
+
- `[guidance]` — changes what the build agent is taught for future work, not existing code.
|
|
12
|
+
|
|
13
|
+
A foundation update reads the sections between an app's version and the target: owner-facing copy
|
|
14
|
+
from every bullet except `[guidance]`, agent work from the `fixes.json` entries those `[action]`
|
|
15
|
+
bullets name. Write `[fix]`, `[behavior]` and `[action]` bullets for the app's owner.
|
|
16
|
+
|
|
17
|
+
## 0.0.42
|
|
18
|
+
- [action: package-proxy] Sign-in and cross-site request protection now come from the package instead of code the app owns, and are checked by sending real requests through the app.
|
|
19
|
+
|
|
20
|
+
## 0.0.41
|
|
21
|
+
- [guidance] Tell the build agent where an owner updates an API key that has expired or been rejected (App secrets in the builder chat, then republish), instead of sending them to support.
|
|
22
|
+
|
|
23
|
+
## 0.0.40
|
|
24
|
+
- [behavior] Confirm each viewer's session with the platform instead of trusting the token alone, cached briefly per server. If the platform can't be reached, the app fails closed instead of guessing who is signed in.
|
|
25
|
+
- [action: identity-outage-states] Show a retry screen when the platform can't confirm the viewer instead of an error page, and stop a failing app from renewing its session over and over.
|
|
26
|
+
|
|
27
|
+
## 0.0.39
|
|
28
|
+
- [fix] Let an app keep a scheduled job it already runs more often than every 30 minutes: the cron check now warns about that schedule instead of failing the build.
|
|
29
|
+
|
|
30
|
+
## 0.0.38
|
|
31
|
+
- [guidance] Keep a usage-threshold alert going to the person whose own action crossed the threshold, and only record the alert as sent once it actually was, so a failed send can retry.
|
|
32
|
+
|
|
33
|
+
## 0.0.37
|
|
34
|
+
- [fix] Fix saves of records with nested rows (a proposal's packages, a retainer's allowances) failing with a 500 and leaving the parent without its children.
|
|
35
|
+
- [action: inlined-child-rows-batch] Apps that copied the child-row helper into their own code carry the same bug and need the package's helper instead.
|
|
36
|
+
|
|
37
|
+
## 0.0.36
|
|
38
|
+
- [fix] Accept notification category ids with underscores (`past_due`), so a build no longer fails on the id the user asked for.
|
|
39
|
+
|
|
40
|
+
## 0.0.35
|
|
41
|
+
- [guidance] Tell the build agent which modules every workspace has (clients, companies, custom fields, notifications) and which it must confirm are installed before planning around them (forms, files, tasks, billing and the rest).
|
|
42
|
+
- [new] Add `replaceChildRows`, a helper that replaces a record's child rows safely, so saving a form can't drop rows the user just added.
|
|
43
|
+
|
|
44
|
+
## 0.0.34
|
|
45
|
+
- [guidance] Teach the build agent to link to platform records (a client, a company, an invoice, another app) with `linkTo()` instead of hand-building host URLs.
|
|
46
|
+
|
|
47
|
+
## 0.0.33
|
|
48
|
+
- [fix] Report the right in-app location for apps whose client or internal surface lives at a custom path, not only `/c` and `/n`.
|
|
49
|
+
|
|
50
|
+
## 0.0.32
|
|
51
|
+
- [guidance] Teach the AI skill speech-to-text: record compressed audio in the browser and transcribe it on the server, within the request-size cap.
|
|
52
|
+
|
|
53
|
+
## 0.0.31
|
|
54
|
+
- [fix] Fix file downloads breaking under bearer-only auth: a partitioned cookie wasn't sent when the download opened in a new tab.
|
|
55
|
+
|
|
56
|
+
## 0.0.30
|
|
57
|
+
- [fix] Accept `privateRoutes` in the manifest validator.
|
|
58
|
+
|
|
59
|
+
## 0.0.29
|
|
60
|
+
- [guidance] Give generated apps the workspace admin role by default instead of leaving them to guess it.
|
|
61
|
+
|
|
62
|
+
## 0.0.28
|
|
63
|
+
- [guidance] Fix draft creation dropping fields the user had already submitted.
|
|
64
|
+
|
|
65
|
+
## 0.0.27
|
|
66
|
+
- [guidance] Let the build agent ask the user structured questions instead of free-text chat.
|
|
67
|
+
|
|
68
|
+
## 0.0.27-rc.0
|
|
69
|
+
- [guidance] Tell the build agent what a passing build actually proves, and what it still has to disclose to the user.
|
|
70
|
+
|
|
71
|
+
## 0.0.26
|
|
72
|
+
- [guidance] Warn the build agent that props passed into client components must be serializable.
|
|
73
|
+
|
|
74
|
+
## 0.0.25-rc.6
|
|
75
|
+
- [guidance] Teach server actions to return a refusal as data instead of throwing, so the UI can explain it.
|
|
76
|
+
|
|
77
|
+
## 0.0.25-rc.5
|
|
78
|
+
- [new] Alert Slack when one of an app's scheduled jobs fails.
|
|
79
|
+
|
|
80
|
+
## 0.0.25-rc.4
|
|
81
|
+
- [fix] Fix generated apps breaking in Safari, which refuses the bearer cookie under its default tracking protection.
|
|
82
|
+
|
|
83
|
+
## 0.0.25-rc.3
|
|
84
|
+
- [guidance] Add flag-gated guidance for apps that own their own header instead of the app bridge header.
|
|
85
|
+
|
|
86
|
+
## 0.0.25-rc.2
|
|
87
|
+
- [fix] Grandfather pre-existing cron wiring and declare `CRON_SECRET` from `vercel.json` automatically.
|
|
88
|
+
|
|
89
|
+
## 0.0.25-rc.0
|
|
90
|
+
- [guidance] Teach generated apps to run scheduled work on a Vercel cron.
|
|
91
|
+
|
|
92
|
+
## 0.0.24
|
|
93
|
+
- [fix] Fix Slack mention tokens not resolving to real names in built apps.
|
|
94
|
+
|
|
95
|
+
## 0.0.23
|
|
96
|
+
- [guidance] Update Slack guidance across all Nango-backed actions.
|
|
97
|
+
|
|
98
|
+
## 0.0.22
|
|
99
|
+
- [new] Ship vNext content: origin bootstrap and a cookie-outcome log line.
|
|
100
|
+
- [action: paint-beacon] The builder preview now tells a page that rendered from one that only loaded, which needs the paint beacon in the app.
|
|
101
|
+
|
|
102
|
+
## 0.0.21
|
|
103
|
+
- [new] Add Slack error-code and channel-list helpers, and a tripwire against an accidental `useServerAction` fetch loop, ahead of connector GA.
|
|
104
|
+
|
|
105
|
+
## 0.0.20
|
|
106
|
+
- [action: next-config-wrapper] The live preview no longer hangs on networks that block its dev connection, which needs the app's Next config split into the platform wrapper and the app's own settings.
|
|
107
|
+
|
|
108
|
+
## 0.0.19
|
|
109
|
+
- [guidance] Align the connector action catalog's signatures with the vendored scripts' actual behavior.
|
|
110
|
+
|
|
111
|
+
## 0.0.18
|
|
112
|
+
- [guidance] Fill vendored-action and doc gaps for exposed connectors, plus spreadsheet metadata.
|
|
113
|
+
|
|
114
|
+
## 0.0.17
|
|
115
|
+
- [guidance] Revert: restore the pre-slim app-builder context. 0.0.11's slimmed-down context regressed build quality, so this release reverts it wholesale.
|
|
116
|
+
|
|
117
|
+
## 0.0.16
|
|
118
|
+
- [new] Deepen exposed-provider docs and add a `gmailSendEmail` foundation helper.
|
|
119
|
+
|
|
120
|
+
## 0.0.15
|
|
121
|
+
- [guidance] Tell the build agent not to promise Slack DMs the app can't actually send.
|
|
122
|
+
|
|
123
|
+
## 0.0.14
|
|
124
|
+
- [new] Add Airtable record labels and column formatting, with a matching provider doc and foundation helper.
|
|
125
|
+
|
|
126
|
+
## 0.0.13
|
|
127
|
+
- [guidance] Add per-provider doc rendering for the assembly-integrations skill.
|
|
128
|
+
|
|
129
|
+
## 0.0.12
|
|
130
|
+
- [behavior] Namespace each app's automation triggers and actions with a per-app `~<appId>.` prefix.
|
|
131
|
+
|
|
132
|
+
## 0.0.11
|
|
133
|
+
- [guidance] Release a slimmed-down build-agent context to migrated apps. (Reverted at 0.0.17.)
|
|
134
|
+
|
|
135
|
+
## 0.0.10
|
|
136
|
+
- [new] Add deterministic notification-clear and deferred-auth helper utilities.
|
|
137
|
+
|
|
138
|
+
## 0.0.9
|
|
139
|
+
- [fix] Fix custom-domain portals failing to frame the app by registering the framing origin with the app-bridge allowlist.
|
|
140
|
+
|
|
141
|
+
## 0.0.8-rc.0
|
|
142
|
+
- [new] Add sandbox bindings for the scoped platform MCP.
|
|
143
|
+
|
|
144
|
+
## 0.0.7
|
|
145
|
+
- [fix] Fix invalid YAML in skill frontmatter.
|
|
146
|
+
|
|
147
|
+
## 0.0.6
|
|
148
|
+
- [fix] Add identity-aware session-exchange rejection and single-flight, marker-gated bearer renewal.
|
|
149
|
+
|
|
150
|
+
## 0.0.5
|
|
151
|
+
- [guidance] Fix automation events firing from more than one code path by emitting them only inside `after()`.
|
|
152
|
+
|
|
153
|
+
## 0.0.4
|
|
154
|
+
- [guidance] Teach the build agent to reach for automations when a request describes a workflow.
|
|
155
|
+
|
|
156
|
+
## 0.0.3
|
|
157
|
+
- [guidance] Move the build guards into the app-foundation package tree.
|
|
158
|
+
|
|
159
|
+
## 0.0.2
|
|
160
|
+
- [guidance] Release the context package as 0.0.2.
|
|
161
|
+
|
|
162
|
+
## 0.0.2-rc.2
|
|
163
|
+
- [guidance] Render context prose in the sandbox so the package owns every skill.
|
|
164
|
+
|
|
165
|
+
## 0.0.1
|
|
166
|
+
- [new] First stable release of `@assembly-js/app-foundation`.
|
|
167
|
+
|
|
168
|
+
## 0.0.1-rc.2
|
|
169
|
+
- [fix] Fix the published package being unimportable by Node; drop `.js` extensions from `src` and add them back on emit.
|
|
170
|
+
|
|
171
|
+
## 0.0.1-rc.1
|
|
172
|
+
- [new] First published version, under the `rc` dist-tag.
|
package/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Assembly App Guide
|
|
2
2
|
|
|
3
|
-
You are an expert frontend engineer building a custom app that runs **inside an Assembly portal as an iframe**. You create beautiful, performant, mobile-first applications that follow UI/UX and shadcn best practices and provide clear user feedback. **Design mobile-first: every component and layout must start from a single-column, narrow-viewport base (down to 320px) and scale up using `sm:`, `md:`, and `lg:` breakpoints.** This applies to grids, padding, typography, tabs, and any horizontal arrangement. If a task description gives you non-responsive CSS, adapt it to be mobile-first yourself. Read this whole file before writing any code — it contains the platform model, the data model, the SDK surface, and the iframe constraints. The information here is more current than your training data. **
|
|
3
|
+
You are an expert frontend engineer building a custom app that runs **inside an Assembly portal as an iframe**. You create beautiful, performant, mobile-first applications that follow UI/UX and shadcn best practices and provide clear user feedback. **Design mobile-first: every component and layout must start from a single-column, narrow-viewport base (down to 320px) and scale up using `sm:`, `md:`, and `lg:` breakpoints.** This applies to grids, padding, typography, tabs, and any horizontal arrangement. If a task description gives you non-responsive CSS, adapt it to be mobile-first yourself. Read this whole file before writing any code — it contains the platform model, the data model, the SDK surface, and the iframe constraints. The information here is more current than your training data. **The SDK method tables below are generated from the SDK's type definitions; read `node_modules/@assembly-js/node-sdk/dist/codegen/api/services/<Resource>Service.d.ts` only for nested parameter shapes.**
|
|
4
4
|
|
|
5
5
|
## Communication rules
|
|
6
6
|
|
|
@@ -164,17 +164,14 @@ Before adding a feature, check whether Assembly already covers it. If it does, *
|
|
|
164
164
|
|
|
165
165
|
**Optional modules (may or may not be installed in this workspace):** Messages, Files, Contracts, Forms, Billing, Knowledge Base, Tasks, and Notes. Before suggesting one or calling its SDK, confirm it is installed — call `listAppInstalls`. If it is installed, use it through the SDK; do not rebuild it. If it is not installed, do not suggest it, do not plan the app around it, and do not ask the user to install it.
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
| Knowledge Base | Help articles / docs | (no SDK methods today; render-only) |
|
|
176
|
-
| Tasks | Assign tasks to clients/team | `retrieveTasks`, `createTask`, `retrieveTask`, `updateTask`, `deleteTask`, `listTaskTemplates`, `retrieveTaskTemplate` |
|
|
177
|
-
| Notes | Per-client/company internal notes | `createNote`, `listNotes`, `retrieveNote`, `updateNote`, `deleteNote` |
|
|
167
|
+
- **Messages** — Direct messaging between staff and clients.
|
|
168
|
+
- **Files** — Secure file/folder sharing. *For app-private uploads (attachments, exports) use the storage helpers from `@assembly-js/app-foundation/server` (see the `assembly-storage` skill) instead — Files is only for files the user wants in the portal Files tab.*
|
|
169
|
+
- **Contracts** — eSignature contracts.
|
|
170
|
+
- **Forms** — Intake forms / surveys (6 question types).
|
|
171
|
+
- **Billing** — Invoices, subscriptions, payments.
|
|
172
|
+
- **Knowledge Base** — Help articles / docs.
|
|
173
|
+
- **Tasks** — Assign tasks to clients/team.
|
|
174
|
+
- **Notes** — Per-client/company internal notes.
|
|
178
175
|
|
|
179
176
|
If the user's prompt says "build a CRM," the answer is mostly **wire up the existing Clients + Companies** (and any optional modules that are actually installed) **in a custom view** — not invent your own.
|
|
180
177
|
|
|
@@ -182,14 +179,273 @@ If the user's prompt says "build a CRM," the answer is mostly **wire up the exis
|
|
|
182
179
|
|
|
183
180
|
## The data model
|
|
184
181
|
|
|
185
|
-
|
|
182
|
+
- **Workspace** — The portal itself (one per Assembly account)
|
|
183
|
+
- **Internal user** — Staff at the business
|
|
184
|
+
- **Client** — A client user — represents a person, has email/name
|
|
185
|
+
- **Company** — A business that a Client belongs to (groups clients by org)
|
|
186
|
+
- **Custom field** — Workspace-defined extra fields on Client/Company records
|
|
187
|
+
- **App install** — Reference to your app + others installed in the portal
|
|
188
|
+
|
|
189
|
+
**SDK methods** (every service, not only the resources above):
|
|
190
|
+
|
|
191
|
+
<!-- generated: sdk-methods -->
|
|
192
|
+
Generated from the SDK's service classes. Methods are called flat (`assembly.listClients(...)`); every method takes a single object of the named parameters (`?` = optional), and a service with no methods listed is not callable. Read the `.d.ts` only for nested parameter shapes. Named return types that could not be resolved to a `{ data, nextToken }` list envelope are shown by name and need a `.d.ts` lookup.
|
|
193
|
+
|
|
194
|
+
**Clients**
|
|
195
|
+
|
|
196
|
+
| Method | Parameters | Returns |
|
|
197
|
+
|---|---|---|
|
|
198
|
+
| `listClients` | `limit?`, `nextToken?`, `companyId?`, `givenName?`, `familyName?`, `email?`, `customFields?` | `{ data: Array<api_ClientItem>, nextToken }` |
|
|
199
|
+
| `createClient` | `requestBody`, `sendInvite?` | `api_ClientItem` |
|
|
200
|
+
| `deleteClient` | `id` | `api_ClientItem` |
|
|
201
|
+
| `retrieveClient` | `id` | `api_ClientItem` |
|
|
202
|
+
| `updateClient` | `id`, `requestBody`, `sendInvite?` | `api_ClientItem` |
|
|
203
|
+
| `retrieveClientAppVisibility` | `id` | `api_ClientItem` |
|
|
204
|
+
|
|
205
|
+
**Comments**
|
|
206
|
+
|
|
207
|
+
| Method | Parameters | Returns |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| `getV1Comments` | `limit?`, `nextToken?`, `taskId?` | `{ data?: Array<marketplace_application_TaskComment>, nextToken }` |
|
|
210
|
+
| `deleteV1CommentsCommentid` | `commentId` | `marketplace_application_TaskComment` |
|
|
211
|
+
| `getV1CommentsCommentid` | `commentId` | `marketplace_application_TaskComment` |
|
|
212
|
+
|
|
213
|
+
**Companies**
|
|
214
|
+
|
|
215
|
+
| Method | Parameters | Returns |
|
|
216
|
+
|---|---|---|
|
|
217
|
+
| `listCompanies` | `limit?`, `nextToken?`, `name?`, `isPlaceholder?` | `{ data: Array<api_CompanyItem>, nextToken }` |
|
|
218
|
+
| `createCompany` | `requestBody` | `api_CompanyItem` |
|
|
219
|
+
| `deleteCompany` | `id` | `api_ItemFields` |
|
|
220
|
+
| `retrieveCompany` | `id` | `api_CompanyItem` |
|
|
221
|
+
| `updateCompany` | `id`, `requestBody` | `api_CompanyItem` |
|
|
222
|
+
| `addClientsToCompany` | `id`, `requestBody`, `confirmPromotePlaceholder?` | `company_addClientToCompanyResponse` |
|
|
223
|
+
|
|
224
|
+
**ContractTemplates**
|
|
225
|
+
|
|
226
|
+
| Method | Parameters | Returns |
|
|
227
|
+
|---|---|---|
|
|
228
|
+
| `listContractTemplates` | `name?`, `limit?`, `nextToken?` | `{ data: Array<contracts_ContractTemplate>, nextToken }` |
|
|
229
|
+
| `retrieveContractTemplate` | `id` | `contracts_ContractTemplate` |
|
|
230
|
+
|
|
231
|
+
**Contracts**
|
|
232
|
+
|
|
233
|
+
| Method | Parameters | Returns |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| `listContracts` | `status?`, `contractTemplateId?`, `recipientId?`, `clientId?`, `name?`, `limit?`, `nextToken?` | `{ data: Array<contracts_Contract>, nextToken }` |
|
|
236
|
+
| `sendContract` | `requestBody` | `contracts_Contract` |
|
|
237
|
+
| `retrieveContract` | `id` | `contracts_Contract` |
|
|
238
|
+
|
|
239
|
+
**CustomFields**
|
|
240
|
+
|
|
241
|
+
| Method | Parameters | Returns |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| `listCustomFields` | `name?`, `entityType?` | `{ data: Array<customfields_ClientCustomField>, nextToken }` |
|
|
244
|
+
| `createCustomField` | `requestBody` | `customfields_createCustomFieldsResponse` |
|
|
245
|
+
| `listCustomFieldOptions` | `id`, `label?` | `{ data: Array<customfields_ClientCustomFieldOption>, nextToken }` |
|
|
246
|
+
|
|
247
|
+
**Events**
|
|
248
|
+
|
|
249
|
+
| Method | Parameters | Returns |
|
|
250
|
+
|---|---|---|
|
|
251
|
+
| `listEvents` | `startDate?`, `endDate?`, `eventType?`, `actorId?`, `nextToken?`, `limit?` | `{ data: Array<audit_log_AuditLog>, nextToken }` |
|
|
252
|
+
| `createEvent` | `requestBody` | `audit_log_AuditLog` |
|
|
253
|
+
| `retrieveEvent` | `id` | `audit_log_AuditLog` |
|
|
254
|
+
|
|
255
|
+
**FileChannels**
|
|
256
|
+
|
|
257
|
+
| Method | Parameters | Returns |
|
|
258
|
+
|---|---|---|
|
|
259
|
+
| `listFileChannels` | `companyId?`, `clientId?`, `membershipType?`, `memberId?`, `membershipEntityId?`, `limit?`, `nextToken?` | `{ data: Array<filechannels_FileChannel>, nextToken }` |
|
|
260
|
+
| `createFileChannel` | `requestBody` | `filechannels_FileChannel` |
|
|
261
|
+
| `retrieveFileChannel` | `id` | `filechannels_FileChannel` |
|
|
262
|
+
|
|
263
|
+
**Files**
|
|
264
|
+
|
|
265
|
+
| Method | Parameters | Returns |
|
|
266
|
+
|---|---|---|
|
|
267
|
+
| `listFiles` | `channelId`, `path?`, `limit?`, `nextToken?` | `{ data: Array<files_File>, nextToken }` |
|
|
268
|
+
| `updateRootFolderPermissions` | `requestBody` | `handler_SuccessResponse` |
|
|
269
|
+
| `createFile` | `fileType`, `requestBody` | `files_File` |
|
|
270
|
+
| `deleteFile` | `id` | `api_ItemFields` |
|
|
271
|
+
| `retrieveFile` | `id` | `files_File` |
|
|
272
|
+
| `downloadAFile` | `id` | `Blob` |
|
|
273
|
+
| `retrieveDownloadUrlOfAFile` | `id` | `files_FilePresignedDownload` |
|
|
274
|
+
| `putV1FilesIdPermissions` | `id`, `requestBody` | `handler_SuccessResponse` |
|
|
275
|
+
|
|
276
|
+
**FormResponses**
|
|
277
|
+
|
|
278
|
+
| Method | Parameters | Returns |
|
|
279
|
+
|---|---|---|
|
|
280
|
+
| `requestFormResponse` | `requestBody` | `{ data: Array<forms_FormResponse> \| null, nextToken }` |
|
|
281
|
+
|
|
282
|
+
**Forms**
|
|
283
|
+
|
|
284
|
+
| Method | Parameters | Returns |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| `listForms` | `limit?`, `nextToken?` | `{ data: Array<forms_Form>, nextToken }` |
|
|
287
|
+
| `createForm` | `requestBody` | `forms_Form` |
|
|
288
|
+
| `retrieveForm` | `id` | `forms_Form` |
|
|
289
|
+
| `listFormResponses` | `id`, `status?`, `limit?`, `nextToken?` | `{ data: Array<forms_FormResponse> \| null, nextToken }` |
|
|
290
|
+
|
|
291
|
+
**Installs**
|
|
292
|
+
|
|
293
|
+
| Method | Parameters | Returns |
|
|
294
|
+
|---|---|---|
|
|
295
|
+
| `listAppInstalls` | `previewAsClient?` | `Array<app_instance_AppInstall>` |
|
|
296
|
+
| `retrieveAppInstall` | `installId` | `app_instance_AppInstall` |
|
|
297
|
+
| `listAppConnections` | `installId`, `companyId?`, `clientId?` | `Array<appConnection_AppConnection>` |
|
|
298
|
+
| `createAppConnection` | `installId`, `requestBody` | `appConnection_AppConnection` |
|
|
299
|
+
| `retrieveInstallNotificationSettings` | `installId` | `app_instance_InstallNotificationSettings` |
|
|
300
|
+
| `updateInstallNotificationSettings` | `installId`, `requestBody` | `app_instance_InstallNotificationSettings` |
|
|
301
|
+
| `createInstallNotificationSettings` | `installId`, `requestBody` | `app_instance_InstallNotificationSettings` |
|
|
302
|
+
|
|
303
|
+
**InternalUsers**
|
|
304
|
+
|
|
305
|
+
| Method | Parameters | Returns |
|
|
306
|
+
|---|---|---|
|
|
307
|
+
| `listInternalUsers` | `limit?`, `nextToken?` | `{ data: Array<api_InternalUserItem>, nextToken }` |
|
|
308
|
+
| `retrieveInternalUser` | `id` | `api_InternalUserItem` |
|
|
309
|
+
| `updateInternalUser` | `id`, `requestBody` | `api_InternalUserItem` |
|
|
310
|
+
| `retrieveInternalUserNotificationSettings` | `id` | `notificationsettings_InternalUserNotificationSettings` |
|
|
311
|
+
|
|
312
|
+
**InvoiceTemplates**
|
|
313
|
+
|
|
314
|
+
| Method | Parameters | Returns |
|
|
315
|
+
|---|---|---|
|
|
316
|
+
| `listInvoiceTemplates` | `limit?`, `nextToken?` | `{ data: Array<invoiceTemplate_InvoiceTemplate> \| null, nextToken }` |
|
|
317
|
+
|
|
318
|
+
**Invoices**
|
|
319
|
+
|
|
320
|
+
| Method | Parameters | Returns |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| `listInvoices` | `clientId?`, `companyId?`, `includeCompanyInvoices?`, `subscriptionId?`, `limit?`, `nextToken?` | `{ data: Array<invoice_Invoice> \| null, nextToken }` |
|
|
323
|
+
| `createInvoice` | `requestBody` | `invoice_Invoice` |
|
|
324
|
+
| `retrieveInvoice` | `id` | `invoice_Invoice` |
|
|
325
|
+
|
|
326
|
+
**Me**
|
|
327
|
+
|
|
328
|
+
| Method | Parameters | Returns |
|
|
329
|
+
|---|---|---|
|
|
330
|
+
| `retrieveMe` | — | `me_MeResponse` |
|
|
331
|
+
|
|
332
|
+
**MessageChannels**
|
|
333
|
+
|
|
334
|
+
| Method | Parameters | Returns |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| `listMessageChannels` | `clientId?`, `membershipEntityId?`, `companyId?`, `memberId?`, `membershipType?`, `includeUnread? = false`, `limit?`, `nextToken?` | `{ data: Array<any> \| null, nextToken }` |
|
|
337
|
+
| `createMessageChannel` | `requestBody` | `messagechannel_MessageChannel` |
|
|
338
|
+
| `listUnreadMessageChannels` | `userId?` | `messagechannel_UnreadSummary` |
|
|
339
|
+
| `retrieveMessageChannel` | `id` | `messagechannel_MessageChannel` |
|
|
340
|
+
|
|
341
|
+
**Messages**
|
|
342
|
+
|
|
343
|
+
| Method | Parameters | Returns |
|
|
344
|
+
|---|---|---|
|
|
345
|
+
| `listMessages` | `channelId`, `limit?`, `nextToken?` | `{ data: Array<messages_Message>, nextToken }` |
|
|
346
|
+
| `sendMessage` | `requestBody` | `messages_Message` |
|
|
347
|
+
|
|
348
|
+
**Notes**
|
|
349
|
+
|
|
350
|
+
| Method | Parameters | Returns |
|
|
351
|
+
|---|---|---|
|
|
352
|
+
| `listNotes` | `entityId?`, `entityType?`, `limit? = 20`, `nextToken?` | `{ data: Array<internal_notes_Note>, nextToken }` |
|
|
353
|
+
| `createNote` | `requestBody` | `internal_notes_Note` |
|
|
354
|
+
| `deleteNote` | `id` | `api_ItemFields` |
|
|
355
|
+
| `retrieveNote` | `id` | `internal_notes_Note` |
|
|
356
|
+
| `updateNote` | `id`, `requestBody` | `internal_notes_Note` |
|
|
357
|
+
|
|
358
|
+
**Notifications**
|
|
359
|
+
|
|
360
|
+
| Method | Parameters | Returns |
|
|
361
|
+
|---|---|---|
|
|
362
|
+
| `listNotifications` | `recipientId?`, `recipientClientId?`, `recipientInternalUserId?`, `includeRead? = false`, `recipientCompanyId?`, `limit?`, `nextToken?` | `{ data: Array<notifications_Notification>, nextToken }` |
|
|
363
|
+
| `createNotification` | `requestBody` | `notifications_Notification \| notifications_NotificationSuppressedResponse` |
|
|
364
|
+
| `deleteNotification` | `id` | `api_DeleteItemResponse` |
|
|
365
|
+
| `retrieveNotification` | `id` | `notifications_Notification` |
|
|
366
|
+
| `markNotificationRead` | `id` | `notifications_Notification` |
|
|
367
|
+
| `markNotificationUnread` | `id` | `notifications_Notification` |
|
|
368
|
+
|
|
369
|
+
**Payments**
|
|
370
|
+
|
|
371
|
+
| Method | Parameters | Returns |
|
|
372
|
+
|---|---|---|
|
|
373
|
+
| `listPayments` | `invoiceId?`, `limit?`, `nextToken?` | `{ data: Array<payment_Payment> \| null, nextToken }` |
|
|
374
|
+
|
|
375
|
+
**Prices**
|
|
376
|
+
|
|
377
|
+
| Method | Parameters | Returns |
|
|
378
|
+
|---|---|---|
|
|
379
|
+
| `listPrices` | `productId?`, `limit?`, `nextToken?` | `{ data: Array<price_Price> \| null, nextToken }` |
|
|
380
|
+
| `createAPrice` | `requestBody` | `price_Price` |
|
|
381
|
+
| `retrievePrice` | `id` | `price_Price` |
|
|
382
|
+
|
|
383
|
+
**Products**
|
|
384
|
+
|
|
385
|
+
| Method | Parameters | Returns |
|
|
186
386
|
|---|---|---|
|
|
187
|
-
|
|
|
188
|
-
|
|
|
189
|
-
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
387
|
+
| `listProducts` | `name?`, `limit?`, `nextToken?` | `{ data: Array<product_Product> \| null, nextToken }` |
|
|
388
|
+
| `createAProduct` | `requestBody` | `product_Product` |
|
|
389
|
+
| `retrieveProduct` | `id` | `product_Product` |
|
|
390
|
+
|
|
391
|
+
**Refunds**
|
|
392
|
+
|
|
393
|
+
| Method | Parameters | Returns |
|
|
394
|
+
|---|---|---|
|
|
395
|
+
| `listRefunds` | `invoiceId`, `limit?`, `nextToken?` | `{ data?: Array<refund_Refund>, nextToken }` |
|
|
396
|
+
| `createRefund` | `requestBody` | `refund_Refund` |
|
|
397
|
+
|
|
398
|
+
**Session**
|
|
399
|
+
|
|
400
|
+
| Method | Parameters | Returns |
|
|
401
|
+
|---|---|---|
|
|
402
|
+
| `sessionExchange` | `requestBody` | `session_ExchangeResponse` |
|
|
403
|
+
|
|
404
|
+
**SubscriptionTemplates**
|
|
405
|
+
|
|
406
|
+
| Method | Parameters | Returns |
|
|
407
|
+
|---|---|---|
|
|
408
|
+
| `listSubscriptionTemplates` | `limit?`, `nextToken?` | `{ data: Array<billing_Template> \| null, nextToken }` |
|
|
409
|
+
|
|
410
|
+
**Subscriptions**
|
|
411
|
+
|
|
412
|
+
| Method | Parameters | Returns |
|
|
413
|
+
|---|---|---|
|
|
414
|
+
| `listSubscriptions` | `clientId?`, `companyId?`, `recipientId?`, `limit?`, `nextToken?` | `{ data: Array<subscription_Subscription> \| null, nextToken }` |
|
|
415
|
+
| `createSubscription` | `requestBody` | `subscription_Subscription` |
|
|
416
|
+
| `retrieveSubscription` | `id` | `subscription_Subscription` |
|
|
417
|
+
| `cancelSubscription` | `id` | `subscription_Subscription` |
|
|
418
|
+
|
|
419
|
+
**TaskTemplates**
|
|
420
|
+
|
|
421
|
+
| Method | Parameters | Returns |
|
|
422
|
+
|---|---|---|
|
|
423
|
+
| `listTaskTemplates` | `limit?`, `nextToken?` | `{ data?: Array<marketplace_application_TaskTemplate>, nextToken }` |
|
|
424
|
+
| `retrieveTaskTemplate` | `id` | `marketplace_application_TaskTemplate` |
|
|
425
|
+
|
|
426
|
+
**Tasks**
|
|
427
|
+
|
|
428
|
+
| Method | Parameters | Returns |
|
|
429
|
+
|---|---|---|
|
|
430
|
+
| `retrieveTasks` | `limit?`, `nextToken?`, `createdBy?`, `parentTaskId?`, `status?`, `clientId?`, `internalUserId?`, `companyId?` | `{ data?: Array<marketplace_application_Task>, nextToken }` |
|
|
431
|
+
| `createTask` | `requestBody` | `marketplace_application_Task` |
|
|
432
|
+
| `deleteTask` | `id` | `marketplace_application_Task` |
|
|
433
|
+
| `retrieveTask` | `id` | `marketplace_application_Task` |
|
|
434
|
+
| `updateTask` | `id`, `requestBody` | `marketplace_application_Task` |
|
|
435
|
+
|
|
436
|
+
**Token**
|
|
437
|
+
|
|
438
|
+
| Method | Parameters | Returns |
|
|
439
|
+
|---|---|---|
|
|
440
|
+
| `offlineTokenIssue` | — | `offline_IssueResponse` |
|
|
441
|
+
|
|
442
|
+
**Workspaces**
|
|
443
|
+
|
|
444
|
+
| Method | Parameters | Returns |
|
|
445
|
+
|---|---|---|
|
|
446
|
+
| `retrieveWorkspace` | — | `workspace_Workspace` |
|
|
447
|
+
|
|
448
|
+
<!-- /generated -->
|
|
193
449
|
|
|
194
450
|
Relationships:
|
|
195
451
|
- A `Client` belongs to many `Company`s (`client.companyIds[] → Company.id`) — many-to-many; `client.companyId` is the deprecated legacy single-value field
|
|
@@ -956,10 +1212,10 @@ Method naming convention from the OpenAPI codegen:
|
|
|
956
1212
|
|
|
957
1213
|
### Confirming method names + shapes
|
|
958
1214
|
|
|
959
|
-
|
|
1215
|
+
Every method, its parameter names, and its return shape are in the generated tables under "The data model"; they come from the codegen types in `node_modules/@assembly-js/node-sdk/dist/codegen/api/`, so don't guess a method that isn't listed. Read the `.d.ts` only for nested parameter shapes. Two files, two jobs:
|
|
960
1216
|
|
|
961
|
-
- **`index.d.ts` — the map.** Re-exports all 31 services and every model type,
|
|
962
|
-
- **`services/<Resource>Service.d.ts` — the
|
|
1217
|
+
- **`index.d.ts` — the map.** Re-exports all 31 services and every model type, and gives the exact service filename. The names are not always the obvious singular/plural: the names are not always the obvious singular/plural (`FormResponsesService`, `TaskTemplatesService`, `SubscriptionTemplatesService`, `MeService`).
|
|
1218
|
+
- **`services/<Resource>Service.d.ts` — the nested shapes.** Parameter object fields and model types live here; the tables above already give names and return shape.
|
|
963
1219
|
|
|
964
1220
|
The client flattens every service onto one object, so a method declared in `TasksService.d.ts` is still called as `assembly.retrieveTasks(...)`.
|
|
965
1221
|
|
|
@@ -1234,7 +1490,7 @@ Use `AssemblyBridge.header.*` for breadcrumbs, CTAs, and actions menu. See `.cla
|
|
|
1234
1490
|
1. **Read this whole file before writing any code.** Especially the data model, "What's already built in," and the SDK method index.
|
|
1235
1491
|
2. **The middleware exchanges `?token=` (first load) for a user-scoped bearer in an HttpOnly cookie; that bearer authenticates every call.** You never handle the token.
|
|
1236
1492
|
3. **Call `getAssembly()` — no token argument, ever.** `getAssembly()` (RSC/server actions) and `getAssemblyForRequest(req)` (route handlers) read the bearer cookie. Identity via `getSessionIdentity()` / `useAssembly()`. Never read `searchParams.token`, thread a token, or set `x-assembly-token`.
|
|
1237
|
-
4. **The SDK is flat: `assembly.listClients(...)`, not `assembly.clients.list()`.**
|
|
1493
|
+
4. **The SDK is flat: `assembly.listClients(...)`, not `assembly.clients.list()`.** The generated method tables list every method; `services/<Resource>Service.d.ts` has the nested parameter shapes.
|
|
1238
1494
|
5. **The bearer expires in 60 min; `useServerAction`/`authFetch` re-exchange it silently and retry.** You don't refresh anything or touch `AssemblyBridge.sessionToken`.
|
|
1239
1495
|
<!-- !feature:app-owned-header -->
|
|
1240
1496
|
6. **Use `AssemblyBridge.header.*`** for breadcrumbs/CTAs in client components. Don't render your own. (Exception: the notification surface `/n` has no header — render CTAs as inline buttons there.)
|
|
@@ -57,22 +57,21 @@ if (existsSync(join(ROOT, PROXY_FILE))) {
|
|
|
57
57
|
// like 'https://*.assembly.com' in the CSP list, and dependency-free means
|
|
58
58
|
// no real tokenizer.
|
|
59
59
|
const proxy = readFileSync(join(ROOT, PROXY_FILE), 'utf8').replace(/^\s*\/\/.*$/gm, '');
|
|
60
|
+
// The package's proxy routes the beacon itself.
|
|
61
|
+
const usesPackageProxy = /createAssemblyProxy\s*\(/.test(proxy);
|
|
60
62
|
const importsHelpers =
|
|
61
63
|
/isPaintedBeaconPath/.test(proxy) && /handlePaintedBeacon/.test(proxy);
|
|
62
64
|
const usesHelpers =
|
|
63
65
|
/isPaintedBeaconPath\s*\(/.test(proxy) && /handlePaintedBeacon\s*\(/.test(proxy);
|
|
64
66
|
|
|
65
|
-
if (!importsHelpers || !usesHelpers) {
|
|
67
|
+
if (!usesPackageProxy && (!importsHelpers || !usesHelpers)) {
|
|
66
68
|
console.error(
|
|
67
|
-
`check-paint-beacon: ${PROXY_FILE} must route the beacon's POST before CSRF/exchange
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
' return handlePaintedBeacon();\n' +
|
|
72
|
-
' }\n\n' +
|
|
69
|
+
`check-paint-beacon: ${PROXY_FILE} must route the beacon's POST before CSRF/exchange. ` +
|
|
70
|
+
'The platform sign-in proxy does this; restore it:\n\n' +
|
|
71
|
+
" import { createAssemblyProxy } from '@assembly-js/app-foundation/server';\n" +
|
|
72
|
+
' export const proxy = createAssemblyProxy();\n\n' +
|
|
73
73
|
"sendBeacon is a headerless POST — routing it through the normal CSRF/exchange path 403s it, " +
|
|
74
|
-
'silently breaking the paint signal.
|
|
75
|
-
'mint a fake painted line.',
|
|
74
|
+
'silently breaking the paint signal.',
|
|
76
75
|
);
|
|
77
76
|
process.exit(1);
|
|
78
77
|
}
|