headroom-cms 0.1.8 → 0.1.10
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/admin/assets/{AdminsPage-Bt_ekZen.js → AdminsPage-BIWASote.js} +1 -1
- package/admin/assets/AllContentPage-1gXe2OC7.js +1 -0
- package/admin/assets/{ApiKeysPage-BfWCxGhC.js → ApiKeysPage-BBW4ATBx.js} +1 -1
- package/admin/assets/AuditPage-B5GGFWGG.js +1 -0
- package/admin/assets/BlockEditor-CQpF8tYb.css +1 -0
- package/admin/assets/BlockEditor-ClskiZoX.js +176 -0
- package/admin/assets/BlockTypeEditPage-CY0gCPei.js +1 -0
- package/admin/assets/BlockTypesPage-D8Me6OeX.js +1 -0
- package/admin/assets/{BulkActionBar-TRiXXLQd.js → BulkActionBar--35xjnOP.js} +1 -1
- package/admin/assets/CollectionEditPage-y8t0ZO89.js +1 -0
- package/admin/assets/{CollectionsPage-ClplrxNn.js → CollectionsPage-BQmGXpvW.js} +1 -1
- package/admin/assets/{ContentCreatePage-DfYcEH1u.js → ContentCreatePage-DlgxamOe.js} +1 -1
- package/admin/assets/ContentEditPage-WkSbCnnG.js +1 -0
- package/admin/assets/ContentField-D04Uo1Ov.js +1 -0
- package/admin/assets/ContentListPage-BDMx7pWb.js +1 -0
- package/admin/assets/CustomBlockPreview-Cs9bFDh4.js +479 -0
- package/admin/assets/FieldRenderer-wE-mtqZB.js +2 -0
- package/admin/assets/FilterBar-kFcOLffg.js +1 -0
- package/admin/assets/FloatingComposerController-D4uLQfUX-C0Lhbmda.js +1 -0
- package/admin/assets/IconPicker-BrgSAsa_.js +3 -0
- package/admin/assets/{LoginPage-DutieANA.js → LoginPage-Bi7TBzK4.js} +1 -1
- package/admin/assets/MediaField-B-Cz8TlK.js +1 -0
- package/admin/assets/MediaPage-C84p9d1U.js +1 -0
- package/admin/assets/Pagination-CuHwUPHi.js +1 -0
- package/admin/assets/RelationshipPicker-Dv7GaLcU.js +1 -0
- package/admin/assets/{SiteSettingsPage-BtCC3RKc.js → SiteSettingsPage-nBT7NzkA.js} +1 -1
- package/admin/assets/{SiteUserEditPage-ClHmp0T-.js → SiteUserEditPage-DroUTii9.js} +1 -1
- package/admin/assets/SiteUsersPage-iVXPCBPe.js +1 -0
- package/admin/assets/{SitesPage-Bw_WBN6v.js → SitesPage-BefZeWuJ.js} +1 -1
- package/admin/assets/{SubmissionDetailPage-DS08LGxd.js → SubmissionDetailPage-ktmzzOE1.js} +1 -1
- package/admin/assets/SubmissionEditPage-C-ykTI2t.js +1 -0
- package/admin/assets/SubmissionListPage-DA-8deUy.js +1 -0
- package/admin/assets/{TagInput-BILCaC9b.js → TagInput-d-Hw1fkL.js} +1 -1
- package/admin/assets/{TagsPage-DdeZokow.js → TagsPage-BZzDvcKa.js} +1 -1
- package/admin/assets/{UsersPage-B0vLxjrg.js → UsersPage-CnQAOOGF.js} +1 -1
- package/admin/assets/{WebhookEditPage-SlJE4d3z.js → WebhookEditPage-KeS8hmdW.js} +1 -1
- package/admin/assets/{WebhooksPage-C6lGZLpr.js → WebhooksPage-CASjmlPN.js} +1 -1
- package/admin/assets/{card-hXVtlM0q.js → card-CZTHR2Qa.js} +1 -1
- package/admin/assets/checkbox-DEgzM8H9.js +1 -0
- package/admin/assets/{collapsible-B414SspL.js → collapsible-D3d29uJp.js} +1 -1
- package/admin/assets/{command-fvBFHye4.js → command-CdzYw11U.js} +1 -1
- package/admin/assets/contentStatus-CkPi9Dh6.js +1 -0
- package/admin/assets/{core.esm-B_kcYf6n.js → core.esm-DdQHdRkd.js} +2 -2
- package/admin/assets/index-BA3y7HJs.js +18 -0
- package/admin/assets/index-c7UygSvP.css +1 -0
- package/admin/assets/popover-BFw_h3j6.js +1 -0
- package/admin/assets/radix-C5ZmWuuL.js +51 -0
- package/admin/assets/select-dX9e6VDt.js +1 -0
- package/admin/assets/{serializeToText-DR_WnxiI.js → serializeToText-Zin3gYPm.js} +1 -1
- package/admin/assets/{sortable.esm-QyXA6fio.js → sortable.esm-qVEMoaTg.js} +1 -1
- package/admin/assets/{table-DLoIbCQ5.js → table-Dk7eeOt2.js} +1 -1
- package/admin/assets/{textarea-vSXNxwTe.js → textarea-CpDSUg2s.js} +1 -1
- package/admin/assets/useAdminResolver-Bljb4XGQ.js +1 -0
- package/admin/assets/useContent-CW0tm0FY.js +1 -0
- package/admin/assets/useContentSearch-_bwacEth.js +1 -0
- package/admin/assets/{useMedia-e3sqWm_t.js → useMedia-Cu5N4rY8.js} +1 -1
- package/admin/assets/usePageTitle-DYvuJQp6.js +1 -0
- package/admin/assets/useSiteUsers-CKtC_8Jc.js +1 -0
- package/admin/assets/{useTags-f7AVSLuj.js → useTags-ybsMbCst.js} +1 -1
- package/admin/assets/{useWebhooks-BH_r8-Mo.js → useWebhooks-BAB-3sLa.js} +1 -1
- package/admin/assets/yjs-tXBm_srz.js +5 -0
- package/admin/index.html +3 -3
- package/admin/sw.js +1 -1
- package/dist/admin-site.d.ts +12 -0
- package/dist/admin-site.d.ts.map +1 -1
- package/dist/admin-site.js +8 -1
- package/dist/admin-site.js.map +1 -1
- package/dist/api.d.ts +7 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +8 -1
- package/dist/api.js.map +1 -1
- package/dist/collaboration.d.ts +55 -0
- package/dist/collaboration.d.ts.map +1 -0
- package/dist/collaboration.js +141 -0
- package/dist/collaboration.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/storage.d.ts +2 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +33 -0
- package/dist/storage.js.map +1 -1
- package/lambda/api/bootstrap +0 -0
- package/lambda/webhook-worker/bootstrap +0 -0
- package/package.json +1 -1
- package/src/admin-site.ts +20 -1
- package/src/api.ts +15 -1
- package/src/collaboration.ts +187 -0
- package/src/index.ts +44 -4
- package/src/sst-env.d.ts +28 -0
- package/src/storage.ts +35 -0
- package/admin/assets/AllContentPage-CFqEMAl9.js +0 -1
- package/admin/assets/AuditPage-BE0XIUl2.js +0 -1
- package/admin/assets/BlockEditor-6wqsThJ7.js +0 -179
- package/admin/assets/BlockEditor-Cp_wZ2xN.css +0 -1
- package/admin/assets/BlockTypeEditPage-CuNJfZw0.js +0 -1
- package/admin/assets/BlockTypesPage-BIMBVxBs.js +0 -1
- package/admin/assets/CollectionEditPage-BqX_0cC2.js +0 -1
- package/admin/assets/ContentEditPage-D3Rvlktk.js +0 -2
- package/admin/assets/ContentListPage-zmO8Is4d.js +0 -1
- package/admin/assets/CustomBlockPreview-C6HqS4xv.js +0 -479
- package/admin/assets/FieldBuilder-36tfpSyM.js +0 -3
- package/admin/assets/FilterBar-DhRwTqFv.js +0 -1
- package/admin/assets/MediaField-J2TLG_fu.js +0 -1
- package/admin/assets/MediaPage-DZZKMGF4.js +0 -1
- package/admin/assets/RelationshipPicker-CDFs4TMW.js +0 -1
- package/admin/assets/SiteUsersPage-AyJvcVM7.js +0 -1
- package/admin/assets/SubmissionEditPage-Brf-DK2X.js +0 -1
- package/admin/assets/SubmissionListPage-DNMzQZHS.js +0 -1
- package/admin/assets/checkbox-WGrS3sUr.js +0 -1
- package/admin/assets/contentStatus-BmaiYVOm.js +0 -1
- package/admin/assets/index-Cir9tY_P.js +0 -18
- package/admin/assets/index-DACBYsKM.css +0 -1
- package/admin/assets/popover-D5_HjjUC.js +0 -1
- package/admin/assets/radix-C1kb_NqW.js +0 -51
- package/admin/assets/select-_uJYxzeZ.js +0 -1
- package/admin/assets/useAdminResolver-D-LlmquD.js +0 -1
- package/admin/assets/useContent-e8beBIuq.js +0 -1
- package/admin/assets/useContentSearch-DOjveB9t.js +0 -1
- package/admin/assets/useDebouncedValue-C-cQUcLG.js +0 -1
- package/admin/assets/usePageTitle-BNSba9_L.js +0 -1
- package/admin/assets/useSiteUsers-BdnvuM2E.js +0 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collaboration Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* API Gateway WebSocket API + DynamoDB Collab table + Node.js Lambda handler.
|
|
5
|
+
* Deployed at all times but dormant for solo editing — no Lambda invocations
|
|
6
|
+
* and no Collab table writes happen until collaboration is opted into.
|
|
7
|
+
*
|
|
8
|
+
* Supports dev mode (Node.js source with live reload) and package mode
|
|
9
|
+
* (pre-bundled handler).
|
|
10
|
+
*
|
|
11
|
+
* Split into two helpers:
|
|
12
|
+
* - `createCollabTable` — provisions just the DynamoDB Collab table.
|
|
13
|
+
* Must be called BEFORE `createApi`, because the Go API links the
|
|
14
|
+
* Collab table for ticket reads/writes.
|
|
15
|
+
* - `createCollabHandler` — provisions the WebSocket API + Lambda and
|
|
16
|
+
* wires `API_URL` into the Lambda environment so `snapshotToDraft`
|
|
17
|
+
* can `fetch` back into the Go API on `$disconnect`. Must be called
|
|
18
|
+
* AFTER `createApi`, because it needs `api.api.url`.
|
|
19
|
+
*
|
|
20
|
+
* The two halves are merged into a single `CollaborationResources` value
|
|
21
|
+
* by `index.ts` so downstream consumers (admin-site, etc.) see one shape.
|
|
22
|
+
*/
|
|
23
|
+
import path from "path";
|
|
24
|
+
export function createCollabTable(name, _args = {}) {
|
|
25
|
+
// DynamoDB table for collaboration sessions + YJS state
|
|
26
|
+
const collabTable = new sst.aws.Dynamo(`${name}Collab`, {
|
|
27
|
+
fields: {
|
|
28
|
+
pk: "string",
|
|
29
|
+
sk: "string",
|
|
30
|
+
},
|
|
31
|
+
primaryIndex: { hashKey: "pk", rangeKey: "sk" },
|
|
32
|
+
// PascalCase to match the convention used throughout the collab TS
|
|
33
|
+
// package (RoomManager, YjsPersistence) and the Go ticket writer
|
|
34
|
+
// (repository/collab.go). DynamoDB attribute names are case-sensitive;
|
|
35
|
+
// the TTL attribute name must match what writers actually emit.
|
|
36
|
+
ttl: "ExpiresAt",
|
|
37
|
+
});
|
|
38
|
+
return { collabTable };
|
|
39
|
+
}
|
|
40
|
+
export function createCollabHandler(name, args) {
|
|
41
|
+
const { storage, auth, api, collabTable } = args;
|
|
42
|
+
// WebSocket API via raw Pulumi (SST v4 doesn't have a WebSocket component)
|
|
43
|
+
const wsApi = new aws.apigatewayv2.Api(`${name}WsApi`, {
|
|
44
|
+
protocolType: "WEBSOCKET",
|
|
45
|
+
routeSelectionExpression: "$request.body.action",
|
|
46
|
+
});
|
|
47
|
+
const handlerConfig = args.dev
|
|
48
|
+
? {
|
|
49
|
+
handler: args.dev.handler,
|
|
50
|
+
runtime: "nodejs22.x",
|
|
51
|
+
}
|
|
52
|
+
: {
|
|
53
|
+
bundle: path.join(args.pkgRoot, "packages/collab"),
|
|
54
|
+
handler: "index.handler",
|
|
55
|
+
runtime: "nodejs22.x",
|
|
56
|
+
};
|
|
57
|
+
const wsHandler = new sst.aws.Function(`${name}CollabHandler`, {
|
|
58
|
+
...handlerConfig,
|
|
59
|
+
// jsdom is pulled in transitively via @blocknote/server-util (used in
|
|
60
|
+
// src/yjs/converter.ts to convert YJS state to BlockNote blocks during
|
|
61
|
+
// the disconnect snapshot). esbuild does not auto-bundle jsdom's
|
|
62
|
+
// xhr-sync-worker.js because it's spawned dynamically at runtime
|
|
63
|
+
// (`new Worker(__dirname + "/xhr-sync-worker.js")`), so the worker file
|
|
64
|
+
// is missing on disk in the deployed Lambda and cold-starts fail with
|
|
65
|
+
// "Cannot find module './xhr-sync-worker.js'". Adding jsdom to
|
|
66
|
+
// `nodejs.install` excludes it from the esbuild bundle and instead
|
|
67
|
+
// installs it (with its full directory tree, including the worker file)
|
|
68
|
+
// into the function's node_modules/ at deploy time.
|
|
69
|
+
nodejs: {
|
|
70
|
+
install: ["jsdom"],
|
|
71
|
+
},
|
|
72
|
+
timeout: "30 seconds",
|
|
73
|
+
memory: "512 MB",
|
|
74
|
+
environment: {
|
|
75
|
+
COLLAB_TABLE: collabTable.name,
|
|
76
|
+
DRAFT_CONTENT_TABLE: storage.draftContent.name,
|
|
77
|
+
BLOCKS_TABLE: storage.blocks.name,
|
|
78
|
+
SITES_TABLE: storage.sites.name,
|
|
79
|
+
USER_POOL_ID: auth.userPool.id,
|
|
80
|
+
USER_POOL_CLIENT_ID: auth.userPoolClient.id,
|
|
81
|
+
WS_API_ENDPOINT: $interpolate `https://${wsApi.id}.execute-api.${aws.getRegionOutput().name}.amazonaws.com/${$app.stage}`,
|
|
82
|
+
// Required by `snapshotToDraft` (packages/collab/src/draft/snapshot.ts)
|
|
83
|
+
// which fetches `${apiUrl}/v1/admin/sites/{host}/content/{id}/draft`
|
|
84
|
+
// on `$disconnect` to persist the YJS room state back to DraftContent.
|
|
85
|
+
// Without this, the URL becomes `undefined/v1/admin/...` and the fetch
|
|
86
|
+
// throws "Failed to parse URL", crashing the disconnect Lambda.
|
|
87
|
+
API_URL: api.api.url,
|
|
88
|
+
// Shared with the Go API. Sent as `X-Headroom-Internal` on the
|
|
89
|
+
// disconnect snapshot PUT so the Go JWT middleware accepts the
|
|
90
|
+
// internal service-to-service call. See packages/api/internal/middleware/jwt.go.
|
|
91
|
+
INTERNAL_SECRET: storage.internalSecret.value,
|
|
92
|
+
// Phase 7.1 "Large documents": S3 bucket for YJS state that exceeds
|
|
93
|
+
// DynamoDB's 400KB per-item cap. See `YjsPersistence.saveState`.
|
|
94
|
+
COLLAB_STATE_BUCKET: storage.collabStateBucket.name,
|
|
95
|
+
},
|
|
96
|
+
link: [
|
|
97
|
+
collabTable,
|
|
98
|
+
storage.draftContent,
|
|
99
|
+
storage.blocks,
|
|
100
|
+
storage.sites,
|
|
101
|
+
storage.internalSecret,
|
|
102
|
+
// S3 link grants the Lambda IAM permissions for s3:GetObject /
|
|
103
|
+
// s3:PutObject on the bucket via SST's resource binding.
|
|
104
|
+
storage.collabStateBucket,
|
|
105
|
+
],
|
|
106
|
+
permissions: [
|
|
107
|
+
{
|
|
108
|
+
actions: ["execute-api:ManageConnections"],
|
|
109
|
+
resources: [$interpolate `arn:aws:execute-api:*:*:${wsApi.id}/*`],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
// Wire up $connect, $default, $disconnect routes
|
|
114
|
+
const integration = new aws.apigatewayv2.Integration(`${name}WsIntegration`, {
|
|
115
|
+
apiId: wsApi.id,
|
|
116
|
+
integrationType: "AWS_PROXY",
|
|
117
|
+
integrationUri: wsHandler.nodes.function.invokeArn,
|
|
118
|
+
});
|
|
119
|
+
for (const routeKey of ["$connect", "$default", "$disconnect"]) {
|
|
120
|
+
new aws.apigatewayv2.Route(`${name}WsRoute${routeKey}`, {
|
|
121
|
+
apiId: wsApi.id,
|
|
122
|
+
routeKey,
|
|
123
|
+
target: $interpolate `integrations/${integration.id}`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
new aws.apigatewayv2.Stage(`${name}WsStage`, {
|
|
127
|
+
apiId: wsApi.id,
|
|
128
|
+
name: $app.stage,
|
|
129
|
+
autoDeploy: true,
|
|
130
|
+
});
|
|
131
|
+
// Grant API Gateway permission to invoke Lambda
|
|
132
|
+
new aws.lambda.Permission(`${name}WsPermission`, {
|
|
133
|
+
action: "lambda:InvokeFunction",
|
|
134
|
+
function: wsHandler.nodes.function.name,
|
|
135
|
+
principal: "apigateway.amazonaws.com",
|
|
136
|
+
sourceArn: $interpolate `${wsApi.executionArn}/*/*`,
|
|
137
|
+
});
|
|
138
|
+
const wsUrl = $interpolate `wss://${wsApi.id}.execute-api.${aws.getRegionOutput().name}.amazonaws.com/${$app.stage}`;
|
|
139
|
+
return { wsApi, wsHandler, wsUrl };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=collaboration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration.js","sourceRoot":"","sources":["../src/collaboration.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type { ImageResources } from "./image.js";
|
|
|
11
11
|
export type { ApiResources } from "./api.js";
|
|
12
12
|
export type { CdnResources } from "./cdn.js";
|
|
13
13
|
export type { SchedulerResources } from "./scheduler.js";
|
|
14
|
+
export type { CollaborationResources } from "./collaboration.js";
|
|
14
15
|
export type { AdminSiteResources } from "./admin-site.js";
|
|
15
16
|
export interface HeadroomCMSArgs {
|
|
16
17
|
/**
|
|
@@ -74,7 +75,17 @@ export interface HeadroomCMSArgs {
|
|
|
74
75
|
adminPath: string;
|
|
75
76
|
/** Go source path for scheduler Lambda, e.g. "packages/scheduler" */
|
|
76
77
|
schedulerHandler?: string;
|
|
78
|
+
/** SST handler for collab Lambda, e.g. "packages/collab/src/index.handler" */
|
|
79
|
+
collabHandler?: string;
|
|
77
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Build-time toggle for the collaboration feature in the admin UI.
|
|
83
|
+
* Defaults to `true`. Set `false` to keep the WebSocket / Collab table
|
|
84
|
+
* deployed but hide the "Collaborate" / "Request collaboration" buttons
|
|
85
|
+
* and refuse to open WebSockets — a kill-switch without teardown. Used
|
|
86
|
+
* to ship the feature to a stage before turning it on for editors.
|
|
87
|
+
*/
|
|
88
|
+
collabEnabled?: boolean;
|
|
78
89
|
}
|
|
79
90
|
export declare class HeadroomCMS {
|
|
80
91
|
readonly apiUrl: $util.Output<string>;
|
|
@@ -82,6 +93,7 @@ export declare class HeadroomCMS {
|
|
|
82
93
|
readonly adminUrl: $util.Output<string>;
|
|
83
94
|
readonly userPoolId: $util.Output<string>;
|
|
84
95
|
readonly userPoolClientId: $util.Output<string>;
|
|
96
|
+
readonly collabWsUrl: $util.Output<string>;
|
|
85
97
|
readonly outputs: Record<string, $util.Output<string>>;
|
|
86
98
|
constructor(name: string, args: HeadroomCMSArgs);
|
|
87
99
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyCH,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAEpE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,cAAc,CAAC,EAAE;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,CAAC;IAEF;;;OAGG;IACH,GAAG,CAAC,EAAE;QACJ,yDAAyD;QACzD,UAAU,EAAE,MAAM,CAAC;QACnB,wEAAwE;QACxE,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gGAAgG;QAChG,oBAAoB,EAAE,MAAM,CAAC;QAC7B,+EAA+E;QAC/E,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qDAAqD;QACrD,SAAS,EAAE,MAAM,CAAC;QAClB,qEAAqE;QACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,8EAA8E;QAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,WAAW;IACtB,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,SAAgB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,SAAgB,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,SAAgB,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAElD,SAAgB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAElD,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe;CA0HhD"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { createImage } from "./image.js";
|
|
|
13
13
|
import { createApi } from "./api.js";
|
|
14
14
|
import { createCdn } from "./cdn.js";
|
|
15
15
|
import { createScheduler } from "./scheduler.js";
|
|
16
|
+
import { createCollabTable, createCollabHandler } from "./collaboration.js";
|
|
16
17
|
import { createAdminSite } from "./admin-site.js";
|
|
17
18
|
/**
|
|
18
19
|
* Resolve the headroom-cms package root directory.
|
|
@@ -44,6 +45,7 @@ export class HeadroomCMS {
|
|
|
44
45
|
adminUrl;
|
|
45
46
|
userPoolId;
|
|
46
47
|
userPoolClientId;
|
|
48
|
+
collabWsUrl;
|
|
47
49
|
outputs;
|
|
48
50
|
constructor(name, args) {
|
|
49
51
|
// Only need pkgRoot for package mode (pre-built artifacts)
|
|
@@ -75,19 +77,38 @@ export class HeadroomCMS {
|
|
|
75
77
|
? { handler: args.dev.imageLambdaHandler }
|
|
76
78
|
: undefined,
|
|
77
79
|
});
|
|
78
|
-
//
|
|
80
|
+
// 5a. Collaboration table (must exist before the API Lambda, which
|
|
81
|
+
// links it for ticket reads/writes).
|
|
82
|
+
const collabTable = createCollabTable(name);
|
|
83
|
+
// 6. API Lambda (Go handler with access to all resources)
|
|
79
84
|
const api = createApi(name, {
|
|
80
85
|
storage,
|
|
81
86
|
auth,
|
|
82
87
|
webhooks,
|
|
83
88
|
image,
|
|
89
|
+
collab: collabTable,
|
|
84
90
|
senderEmail: args.senderEmail,
|
|
85
91
|
pkgRoot,
|
|
86
92
|
dev: args.dev
|
|
87
93
|
? { handler: args.dev.apiHandler }
|
|
88
94
|
: undefined,
|
|
89
95
|
});
|
|
90
|
-
//
|
|
96
|
+
// 5b. Collaboration WebSocket handler (must be created AFTER the API
|
|
97
|
+
// because its Lambda environment includes API_URL = api.api.url, which
|
|
98
|
+
// `snapshotToDraft` uses to PUT the disconnect snapshot back to the
|
|
99
|
+
// Go draft endpoint).
|
|
100
|
+
const collabHandler = createCollabHandler(name, {
|
|
101
|
+
storage,
|
|
102
|
+
auth,
|
|
103
|
+
api,
|
|
104
|
+
collabTable: collabTable.collabTable,
|
|
105
|
+
pkgRoot,
|
|
106
|
+
dev: args.dev?.collabHandler
|
|
107
|
+
? { handler: args.dev.collabHandler }
|
|
108
|
+
: undefined,
|
|
109
|
+
});
|
|
110
|
+
const collab = { ...collabTable, ...collabHandler };
|
|
111
|
+
// 7. Scheduler (EventBridge cron + Go Lambda + lock table)
|
|
91
112
|
const schedulerResources = createScheduler(name, {
|
|
92
113
|
storage,
|
|
93
114
|
api,
|
|
@@ -96,7 +117,7 @@ export class HeadroomCMS {
|
|
|
96
117
|
? { handler: args.dev.schedulerHandler }
|
|
97
118
|
: undefined,
|
|
98
119
|
});
|
|
99
|
-
//
|
|
120
|
+
// 8. CDN (CloudFront distribution + edge functions)
|
|
100
121
|
const cdn = createCdn(name, {
|
|
101
122
|
api,
|
|
102
123
|
image,
|
|
@@ -106,16 +127,18 @@ export class HeadroomCMS {
|
|
|
106
127
|
apiCacheTtl: args.apiCacheTtl,
|
|
107
128
|
domain: args.domain,
|
|
108
129
|
});
|
|
109
|
-
//
|
|
130
|
+
// 9. Admin UI (static site)
|
|
110
131
|
const admin = createAdminSite(name, {
|
|
111
132
|
api,
|
|
112
133
|
cdn,
|
|
113
134
|
auth,
|
|
135
|
+
collab,
|
|
114
136
|
pkgRoot,
|
|
115
137
|
dev: args.dev
|
|
116
138
|
? { adminPath: args.dev.adminPath }
|
|
117
139
|
: undefined,
|
|
118
140
|
domain: args.adminDomain,
|
|
141
|
+
collabEnabled: args.collabEnabled,
|
|
119
142
|
});
|
|
120
143
|
// Expose outputs
|
|
121
144
|
this.apiUrl = api.api.url;
|
|
@@ -123,12 +146,14 @@ export class HeadroomCMS {
|
|
|
123
146
|
this.adminUrl = admin.url;
|
|
124
147
|
this.userPoolId = auth.userPool.id;
|
|
125
148
|
this.userPoolClientId = auth.userPoolClient.id;
|
|
149
|
+
this.collabWsUrl = collab.wsUrl;
|
|
126
150
|
this.outputs = {
|
|
127
151
|
api: api.api.url,
|
|
128
152
|
cdn: cdn.url,
|
|
129
153
|
admin: admin.url,
|
|
130
154
|
userPoolId: auth.userPool.id,
|
|
131
155
|
userPoolClientId: auth.userPoolClient.id,
|
|
156
|
+
collabWs: collab.wsUrl,
|
|
132
157
|
};
|
|
133
158
|
}
|
|
134
159
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,SAAS,cAAc;IACrB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACjE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uDAAuD;QACvD,yCAAyC,CAC1C,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,SAAS,cAAc;IACrB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACjE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uDAAuD;QACvD,yCAAyC,CAC1C,CAAC;AACJ,CAAC;AA+FD,MAAM,OAAO,WAAW;IACN,MAAM,CAAuB;IAC7B,MAAM,CAAuB;IAC7B,QAAQ,CAAuB;IAC/B,UAAU,CAAuB;IACjC,gBAAgB,CAAuB;IACvC,WAAW,CAAuB;IAElC,OAAO,CAAuC;IAE9D,YAAY,IAAY,EAAE,IAAqB;QAC7C,2DAA2D;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;QAEjD,+CAA+C;QAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,gDAAgD;QAChD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACX,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE;gBAC5C,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE;YACpC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACX,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE;gBAC5C,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,0DAA0D;QAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACX,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE;gBAC1C,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,mEAAmE;QACnE,qCAAqC;QACrC,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAE5C,0DAA0D;QAC1D,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE;YAC1B,OAAO;YACP,IAAI;YACJ,QAAQ;YACR,KAAK;YACL,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACX,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE;gBAClC,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,qEAAqE;QACrE,uEAAuE;QACvE,oEAAoE;QACpE,sBAAsB;QACtB,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,EAAE;YAC9C,OAAO;YACP,IAAI;YACJ,GAAG;YACH,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,aAAa;gBAC1B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;gBACrC,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,aAAa,EAAE,CAAC;QAEpD,2DAA2D;QAC3D,MAAM,kBAAkB,GAAG,eAAe,CAAC,IAAI,EAAE;YAC/C,OAAO;YACP,GAAG;YACH,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,gBAAgB;gBAC7B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE;gBACxC,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,oDAAoD;QACpD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE;YAC1B,GAAG;YACH,KAAK;YACL,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QAEH,4BAA4B;QAC5B,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE;YAClC,GAAG;YACH,GAAG;YACH,IAAI;YACJ,MAAM;YACN,OAAO;YACP,GAAG,EAAE,IAAI,CAAC,GAAG;gBACX,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE;gBACnC,CAAC,CAAC,SAAS;YACb,MAAM,EAAE,IAAI,CAAC,WAAW;YACxB,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC,CAAC;QAEH,iBAAiB;QACjB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;QAEhC,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,KAAK,EAAE,KAAK,CAAC,GAAG;YAChB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC5B,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE;YACxC,QAAQ,EAAE,MAAM,CAAC,KAAK;SACvB,CAAC;IACJ,CAAC;CACF"}
|
package/dist/storage.d.ts
CHANGED
|
@@ -16,7 +16,9 @@ export declare function createStorage(name: string): {
|
|
|
16
16
|
relationships: sst.aws.Dynamo;
|
|
17
17
|
siteUsers: sst.aws.Dynamo;
|
|
18
18
|
contentBucket: sst.aws.Bucket;
|
|
19
|
+
collabStateBucket: sst.aws.Bucket;
|
|
19
20
|
kvs: aws.cloudfront.KeyValueStore;
|
|
21
|
+
internalSecret: sst.Secret;
|
|
20
22
|
};
|
|
21
23
|
export type StorageResources = ReturnType<typeof createStorage>;
|
|
22
24
|
//# sourceMappingURL=storage.d.ts.map
|
package/dist/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;;;EAoLzC;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
package/dist/storage.js
CHANGED
|
@@ -119,10 +119,41 @@ export function createStorage(name) {
|
|
|
119
119
|
},
|
|
120
120
|
},
|
|
121
121
|
});
|
|
122
|
+
// Phase 7.1 "Large documents": YJS room state that exceeds DynamoDB's 400KB
|
|
123
|
+
// per-item cap is uploaded here instead of being inlined on the Collab
|
|
124
|
+
// item. Dedicated bucket (vs reusing `contentBucket`) for two reasons:
|
|
125
|
+
// 1. `contentBucket` is `access: "cloudfront"` for media delivery; YJS
|
|
126
|
+
// state must NOT be CDN-fronted (it's per-collaboration-session
|
|
127
|
+
// transient state, never publicly addressable).
|
|
128
|
+
// 2. Lifecycle expiration is much shorter — these objects are recovery
|
|
129
|
+
// fallback for an active collaboration session; the matching Collab
|
|
130
|
+
// table item carries a 24h DynamoDB TTL, so the S3 lifecycle rule
|
|
131
|
+
// cleans up overflow objects on a similar timeline.
|
|
132
|
+
const collabStateBucket = new sst.aws.Bucket(`${name}CollabStateBucket`, {
|
|
133
|
+
transform: {
|
|
134
|
+
bucket: (args) => {
|
|
135
|
+
args.lifecycleRules = [
|
|
136
|
+
{
|
|
137
|
+
id: "expire-collab-state",
|
|
138
|
+
enabled: true,
|
|
139
|
+
expiration: { days: 7 },
|
|
140
|
+
// Keep the matching Collab DynamoDB TTL (24h) as the primary
|
|
141
|
+
// cleanup mechanism; this is a long-stop safety net so orphaned
|
|
142
|
+
// S3 objects don't accumulate forever.
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
122
148
|
const kvs = new aws.cloudfront.KeyValueStore(`${name}KVS`, {
|
|
123
149
|
name: $interpolate `${$app.name}-${$app.stage}-kvs`,
|
|
124
150
|
comment: "Headroom CMS edge data: API keys and site versions",
|
|
125
151
|
});
|
|
152
|
+
// Shared secret for internal service-to-service auth between the collab
|
|
153
|
+
// Lambda and the Go API (`X-Headroom-Internal` header). Both Lambdas read
|
|
154
|
+
// this from their `INTERNAL_SECRET` environment variable. Set the value via
|
|
155
|
+
// `sst secret set HeadroomInternalSecret <value>` (or the namespaced equivalent).
|
|
156
|
+
const internalSecret = new sst.Secret(`${name}InternalSecret`);
|
|
126
157
|
return {
|
|
127
158
|
sites,
|
|
128
159
|
content,
|
|
@@ -135,7 +166,9 @@ export function createStorage(name) {
|
|
|
135
166
|
relationships,
|
|
136
167
|
siteUsers,
|
|
137
168
|
contentBucket,
|
|
169
|
+
collabStateBucket,
|
|
138
170
|
kvs,
|
|
171
|
+
internalSecret,
|
|
139
172
|
};
|
|
140
173
|
}
|
|
141
174
|
//# sourceMappingURL=storage.js.map
|
package/dist/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/lambda/api/bootstrap
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/admin-site.ts
CHANGED
|
@@ -11,11 +11,13 @@ import path from "path";
|
|
|
11
11
|
import type { ApiResources } from "./api.js";
|
|
12
12
|
import type { CdnResources } from "./cdn.js";
|
|
13
13
|
import type { AuthResources } from "./auth.js";
|
|
14
|
+
import type { CollaborationResources } from "./collaboration.js";
|
|
14
15
|
|
|
15
16
|
export interface AdminSiteArgs {
|
|
16
17
|
api: ApiResources;
|
|
17
18
|
cdn: CdnResources;
|
|
18
19
|
auth: AuthResources;
|
|
20
|
+
collab: CollaborationResources;
|
|
19
21
|
pkgRoot: string;
|
|
20
22
|
dev?: {
|
|
21
23
|
/** Path to admin UI source, e.g. "packages/admin" */
|
|
@@ -25,10 +27,23 @@ export interface AdminSiteArgs {
|
|
|
25
27
|
name: string;
|
|
26
28
|
certificateArn: string;
|
|
27
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Build-time toggle for the entire collaboration UI. Defaults to `true`
|
|
32
|
+
* (collab is on whenever the WS infra is deployed). Set to `false` from
|
|
33
|
+
* the consuming SST config to keep the WebSocket / Collab DynamoDB table
|
|
34
|
+
* deployed but hide the "Collaborate" / "Request collaboration" buttons
|
|
35
|
+
* and refuse to open WebSockets — useful as a kill-switch without a full
|
|
36
|
+
* teardown. Plumbs to `VITE_COLLAB_ENABLED` in the admin Vite env; see
|
|
37
|
+
* `packages/admin/src/collab/featureFlag.ts` for the consumer.
|
|
38
|
+
*/
|
|
39
|
+
collabEnabled?: boolean;
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
export function createAdminSite(name: string, args: AdminSiteArgs) {
|
|
31
|
-
const { api, cdn, auth } = args;
|
|
43
|
+
const { api, cdn, auth, collab } = args;
|
|
44
|
+
// Default ON for backward compat — only emit "false" when explicitly
|
|
45
|
+
// disabled so existing stages without the flag set don't change behaviour.
|
|
46
|
+
const collabEnabledStr = args.collabEnabled === false ? "false" : "true";
|
|
32
47
|
|
|
33
48
|
const domainConfig = args.domain
|
|
34
49
|
? {
|
|
@@ -54,6 +69,8 @@ export function createAdminSite(name: string, args: AdminSiteArgs) {
|
|
|
54
69
|
VITE_USER_POOL_ID: auth.userPool.id,
|
|
55
70
|
VITE_USER_POOL_CLIENT_ID: auth.userPoolClient.id,
|
|
56
71
|
VITE_AWS_REGION: aws.getRegionOutput().name,
|
|
72
|
+
VITE_COLLAB_WS_URL: collab.wsUrl,
|
|
73
|
+
VITE_COLLAB_ENABLED: collabEnabledStr,
|
|
57
74
|
},
|
|
58
75
|
domain: domainConfig,
|
|
59
76
|
});
|
|
@@ -84,6 +101,8 @@ export function createAdminSite(name: string, args: AdminSiteArgs) {
|
|
|
84
101
|
'__HEADROOM_USER_POOL_ID__': '${auth.userPool.id}',
|
|
85
102
|
'__HEADROOM_USER_POOL_CLIENT_ID__': '${auth.userPoolClient.id}',
|
|
86
103
|
'__HEADROOM_AWS_REGION__': '${aws.getRegionOutput().name}',
|
|
104
|
+
'__HEADROOM_COLLAB_WS_URL__': '${collab.wsUrl}',
|
|
105
|
+
'__HEADROOM_COLLAB_ENABLED__': '${collabEnabledStr}',
|
|
87
106
|
};
|
|
88
107
|
function walk(d) {
|
|
89
108
|
for (const f of fs.readdirSync(d)) {
|
package/src/api.ts
CHANGED
|
@@ -10,12 +10,19 @@ import type { StorageResources } from "./storage.js";
|
|
|
10
10
|
import type { AuthResources } from "./auth.js";
|
|
11
11
|
import type { WebhookResources } from "./webhooks.js";
|
|
12
12
|
import type { ImageResources } from "./image.js";
|
|
13
|
+
import type { CollabTableResources } from "./collaboration.js";
|
|
13
14
|
|
|
14
15
|
export interface ApiArgs {
|
|
15
16
|
storage: StorageResources;
|
|
16
17
|
auth: AuthResources;
|
|
17
18
|
webhooks: WebhookResources;
|
|
18
19
|
image: ImageResources;
|
|
20
|
+
/**
|
|
21
|
+
* Just the collab DynamoDB table — the API Lambda only links the table
|
|
22
|
+
* for ticket reads/writes, it does NOT depend on the WebSocket handler.
|
|
23
|
+
* (The WS handler is created AFTER the API because its env needs api.url.)
|
|
24
|
+
*/
|
|
25
|
+
collab: CollabTableResources;
|
|
19
26
|
senderEmail: string;
|
|
20
27
|
pkgRoot: string;
|
|
21
28
|
dev?: {
|
|
@@ -25,7 +32,7 @@ export interface ApiArgs {
|
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export function createApi(name: string, args: ApiArgs) {
|
|
28
|
-
const { storage, auth, webhooks, image } = args;
|
|
35
|
+
const { storage, auth, webhooks, image, collab } = args;
|
|
29
36
|
|
|
30
37
|
const handlerConfig = args.dev
|
|
31
38
|
? {
|
|
@@ -67,6 +74,11 @@ export function createApi(name: string, args: ApiArgs) {
|
|
|
67
74
|
RELATIONSHIPS_TABLE: storage.relationships.name,
|
|
68
75
|
SITE_USERS_TABLE: storage.siteUsers.name,
|
|
69
76
|
SES_FROM_EMAIL: args.senderEmail,
|
|
77
|
+
COLLAB_TABLE: collab.collabTable.name,
|
|
78
|
+
// Shared with the collab Lambda. The Go JWT middleware verifies
|
|
79
|
+
// `X-Headroom-Internal` against this on internal service calls
|
|
80
|
+
// (collab → draft snapshot). See packages/api/internal/middleware/jwt.go.
|
|
81
|
+
INTERNAL_SECRET: storage.internalSecret.value,
|
|
70
82
|
},
|
|
71
83
|
link: [
|
|
72
84
|
storage.sites,
|
|
@@ -84,6 +96,8 @@ export function createApi(name: string, args: ApiArgs) {
|
|
|
84
96
|
image.imageSigningSecret,
|
|
85
97
|
storage.relationships,
|
|
86
98
|
storage.siteUsers,
|
|
99
|
+
collab.collabTable,
|
|
100
|
+
storage.internalSecret,
|
|
87
101
|
],
|
|
88
102
|
permissions: [
|
|
89
103
|
{
|