deepspace 0.6.2 → 0.8.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/CHANGELOG.md +44 -0
- package/README.md +22 -8
- package/dist/cli.js +10348 -5025
- package/dist/cli.js.map +1 -1
- package/dist/feature-installer.js +638 -0
- package/dist/feature-installer.js.map +1 -0
- package/dist/index.d.ts +229 -116
- package/dist/index.js +767 -788
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +403 -167
- package/dist/server.js +498 -367
- package/dist/server.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +3 -3
- package/dist/testing.js.map +1 -1
- package/dist/worker.d.ts +541 -159
- package/dist/worker.js +611 -367
- package/dist/worker.js.map +1 -1
- package/features/ai-chat/feature.json +2 -0
- package/features/ai-chat/src/AiChatPage.tsx +2 -3
- package/features/ai-chat/src/ChatPanel.messages.tsx +344 -0
- package/features/ai-chat/src/ChatPanel.stream.ts +397 -0
- package/features/ai-chat/src/ChatPanel.tsx +159 -825
- package/features/ai-chat/src/__tests__/ChatPanel.stream.test.ts +163 -0
- package/features/canvas/src/CanvasListPage.tsx +1 -1
- package/features/docs/feature.json +4 -8
- package/features/docs/src/DocsEditorPage.tsx +33 -326
- package/features/docs/src/DocsListPage.tsx +33 -29
- package/features/docs/src/InviteDialog.tsx +11 -40
- package/features/docs/src/__tests__/docs-presence-access.test.ts +71 -0
- package/features/docs/src/docs-library-types.ts +28 -3
- package/features/docs/src/docs-ui.css +1 -4
- package/features/docs/src/use-docs-presence-access.ts +330 -0
- package/features/file-attachments/feature.json +2 -2
- package/features/file-attachments/src/AttachmentPreview.tsx +428 -0
- package/features/file-attachments/src/AttachmentsPage.tsx +100 -462
- package/features/file-attachments/src/useFilePreview.ts +54 -68
- package/features/file-manager/src/FileManagerPage.tsx +1 -1
- package/features/integration-test/src/integration.spec.ts +1 -1
- package/features/items/feature.json +1 -5
- package/features/items/src/ItemsPage.tsx +207 -135
- package/features/landing/feature.json +3 -0
- package/features/landing/src/LandingPage.tsx +4 -18
- package/features/leaderboard/feature.json +1 -5
- package/features/leaderboard/src/LeaderboardPage.tsx +333 -198
- package/features/messaging/feature.json +0 -4
- package/features/messaging/src/ChatMultiPage.tsx +1 -3
- package/features/messaging/src/ChatPage.tsx +1 -3
- package/features/messaging/src/components/chat/MessageActionSheet.tsx +40 -16
- package/features/search-bar/feature.json +8 -3
- package/features/search-bar/src/SearchOverlay.tsx +108 -252
- package/features/search-bar/src/__tests__/search-model.test.ts +40 -0
- package/features/search-bar/src/search-model.ts +223 -0
- package/features/tasks/src/TasksPage.tsx +3 -3
- package/features/topbar/src/Topbar.tsx +0 -17
- package/package.json +1 -2
- package/features/docs/src/docs-favorites.ts +0 -18
- package/features/docs/src/use-yjs-room-with-awareness.ts +0 -289
- package/features/file-attachments/src/attachments-constants.ts +0 -9
- package/features/items/src/items-constants.ts +0 -10
- package/features/leaderboard/src/leaderboard-constants.ts +0 -21
- package/features/messaging/src/components/chat/ReactionPicker.tsx +0 -2
- package/scripts/add-feature.cjs +0 -807
package/dist/worker.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import * as Y from 'yjs';
|
|
|
2
2
|
import { LanguageModel, ToolSet, ModelMessage } from 'ai';
|
|
3
3
|
import * as zod_v4_core from 'zod/v4/core';
|
|
4
4
|
import * as zod from 'zod';
|
|
5
|
+
import * as better_auth_plugins from 'better-auth/plugins';
|
|
5
6
|
import * as better_auth from 'better-auth';
|
|
6
7
|
import { betterAuth } from 'better-auth';
|
|
7
|
-
import
|
|
8
|
+
import { Hono } from 'hono';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Wire protocol constants.
|
|
@@ -937,7 +938,7 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
937
938
|
private handleWebSocketUpgrade;
|
|
938
939
|
webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
|
|
939
940
|
webSocketClose(ws: WebSocket, _code: number, _reason: string): Promise<void>;
|
|
940
|
-
webSocketError(
|
|
941
|
+
webSocketError(_ws: WebSocket, error: unknown): Promise<void>;
|
|
941
942
|
alarm(): Promise<void>;
|
|
942
943
|
/**
|
|
943
944
|
* Called when a new WebSocket connects (after auth parsing).
|
|
@@ -1035,6 +1036,95 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
1035
1036
|
protected broadcastBinary(data: Uint8Array | ArrayBuffer, exclude?: WebSocket): void;
|
|
1036
1037
|
}
|
|
1037
1038
|
|
|
1039
|
+
/**
|
|
1040
|
+
* Shared type definitions for the DeepSpace SDK
|
|
1041
|
+
*
|
|
1042
|
+
* Types used by both client-side SDK and server-side workers.
|
|
1043
|
+
*/
|
|
1044
|
+
type ColumnInterpretation = {
|
|
1045
|
+
kind: 'plain';
|
|
1046
|
+
} | {
|
|
1047
|
+
kind: 'currency';
|
|
1048
|
+
symbol: string;
|
|
1049
|
+
decimals: number;
|
|
1050
|
+
} | {
|
|
1051
|
+
kind: 'date';
|
|
1052
|
+
format?: string;
|
|
1053
|
+
} | {
|
|
1054
|
+
kind: 'datetime';
|
|
1055
|
+
format?: string;
|
|
1056
|
+
} | {
|
|
1057
|
+
kind: 'boolean';
|
|
1058
|
+
trueLabel?: string;
|
|
1059
|
+
falseLabel?: string;
|
|
1060
|
+
} | {
|
|
1061
|
+
kind: 'percent';
|
|
1062
|
+
decimals?: number;
|
|
1063
|
+
} | {
|
|
1064
|
+
kind: 'select';
|
|
1065
|
+
options: string[];
|
|
1066
|
+
} | {
|
|
1067
|
+
kind: 'multiselect';
|
|
1068
|
+
options: string[];
|
|
1069
|
+
} | {
|
|
1070
|
+
kind: 'url';
|
|
1071
|
+
} | {
|
|
1072
|
+
kind: 'email';
|
|
1073
|
+
} | {
|
|
1074
|
+
kind: 'json';
|
|
1075
|
+
} | {
|
|
1076
|
+
kind: 'reference';
|
|
1077
|
+
targetTable: string;
|
|
1078
|
+
displayColumn: string;
|
|
1079
|
+
};
|
|
1080
|
+
interface ColumnDefinition {
|
|
1081
|
+
/** Stable ID override (survives renames). Falls back to `col_{name}`. */
|
|
1082
|
+
id?: string;
|
|
1083
|
+
name: string;
|
|
1084
|
+
storage: 'number' | 'text';
|
|
1085
|
+
interpretation: ColumnInterpretation | string;
|
|
1086
|
+
expression?: string;
|
|
1087
|
+
userBound?: boolean;
|
|
1088
|
+
immutable?: boolean;
|
|
1089
|
+
required?: boolean;
|
|
1090
|
+
default?: unknown;
|
|
1091
|
+
timestampTrigger?: {
|
|
1092
|
+
field: string;
|
|
1093
|
+
value?: unknown;
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
type PermissionLevel = boolean | 'own' | 'unclaimed-or-own' | 'collaborator' | 'team' | 'access' | 'published' | 'shared';
|
|
1097
|
+
interface RolePermissions {
|
|
1098
|
+
read: PermissionLevel;
|
|
1099
|
+
/** Create has no existing record to evaluate, so it is an explicit grant. */
|
|
1100
|
+
create: boolean;
|
|
1101
|
+
update: PermissionLevel;
|
|
1102
|
+
delete: PermissionLevel;
|
|
1103
|
+
/** If set, only these columns can be updated by this role. */
|
|
1104
|
+
writableFields?: string[];
|
|
1105
|
+
}
|
|
1106
|
+
interface CollectionSchema {
|
|
1107
|
+
name: string;
|
|
1108
|
+
/** Every collection is stored in typed SQL columns. */
|
|
1109
|
+
columns: ColumnDefinition[];
|
|
1110
|
+
/** Composite uniqueness constraint (for example `['userId', 'taskId']`). */
|
|
1111
|
+
uniqueOn?: string[];
|
|
1112
|
+
/** Ownership column; defaults to the row creator. */
|
|
1113
|
+
ownerField?: string;
|
|
1114
|
+
/** Column containing a JSON array of collaborator user ids. */
|
|
1115
|
+
collaboratorsField?: string;
|
|
1116
|
+
/** Column containing the team id used by team permission rules. */
|
|
1117
|
+
teamField?: string;
|
|
1118
|
+
/** A string is public when equal to `public`; an object supplies an exact value. */
|
|
1119
|
+
visibilityField?: string | {
|
|
1120
|
+
field: string;
|
|
1121
|
+
value: unknown;
|
|
1122
|
+
};
|
|
1123
|
+
/** Permissions per role; `*` is the catch-all role. */
|
|
1124
|
+
permissions: Record<string, RolePermissions>;
|
|
1125
|
+
/** Default role assigned on the `users` collection. */
|
|
1126
|
+
defaultRole?: string;
|
|
1127
|
+
}
|
|
1038
1128
|
interface Query {
|
|
1039
1129
|
collection: string;
|
|
1040
1130
|
where?: Record<string, unknown>;
|
|
@@ -1158,8 +1248,6 @@ interface ConnectionAttachment extends UserAttachment {
|
|
|
1158
1248
|
subscriptions: Subscription[];
|
|
1159
1249
|
/** Yjs docs this connection is editing */
|
|
1160
1250
|
yjsSubscriptions: YjsSubscription[];
|
|
1161
|
-
/** Yjs client ID for awareness */
|
|
1162
|
-
yjsClientId?: number;
|
|
1163
1251
|
/** Client-side Yjs awareness clientId (extracted from first awareness message) */
|
|
1164
1252
|
awarenessClientId?: number;
|
|
1165
1253
|
}
|
|
@@ -1184,63 +1272,7 @@ interface HandlerContext {
|
|
|
1184
1272
|
*
|
|
1185
1273
|
* All collections use typed SQL columns. No document-mode / fields-based storage.
|
|
1186
1274
|
*/
|
|
1187
|
-
|
|
1188
|
-
kind: 'plain';
|
|
1189
|
-
} | {
|
|
1190
|
-
kind: 'currency';
|
|
1191
|
-
symbol: string;
|
|
1192
|
-
decimals: number;
|
|
1193
|
-
} | {
|
|
1194
|
-
kind: 'date';
|
|
1195
|
-
format?: string;
|
|
1196
|
-
} | {
|
|
1197
|
-
kind: 'datetime';
|
|
1198
|
-
format?: string;
|
|
1199
|
-
} | {
|
|
1200
|
-
kind: 'boolean';
|
|
1201
|
-
trueLabel?: string;
|
|
1202
|
-
falseLabel?: string;
|
|
1203
|
-
} | {
|
|
1204
|
-
kind: 'percent';
|
|
1205
|
-
decimals?: number;
|
|
1206
|
-
} | {
|
|
1207
|
-
kind: 'select';
|
|
1208
|
-
options: string[];
|
|
1209
|
-
} | {
|
|
1210
|
-
kind: 'multiselect';
|
|
1211
|
-
options: string[];
|
|
1212
|
-
} | {
|
|
1213
|
-
kind: 'url';
|
|
1214
|
-
} | {
|
|
1215
|
-
kind: 'email';
|
|
1216
|
-
} | {
|
|
1217
|
-
kind: 'json';
|
|
1218
|
-
} | {
|
|
1219
|
-
kind: 'reference';
|
|
1220
|
-
targetTable: string;
|
|
1221
|
-
displayColumn: string;
|
|
1222
|
-
};
|
|
1223
|
-
interface ColumnDefinition {
|
|
1224
|
-
/** Stable ID override (survives renames). Falls back to `col_{name}`. */
|
|
1225
|
-
id?: string;
|
|
1226
|
-
name: string;
|
|
1227
|
-
storage: 'number' | 'text';
|
|
1228
|
-
interpretation: ColumnInterpretation | string;
|
|
1229
|
-
expression?: string;
|
|
1230
|
-
/** Auto-populate with current user ID on create. */
|
|
1231
|
-
userBound?: boolean;
|
|
1232
|
-
/** Cannot be changed after initial creation. */
|
|
1233
|
-
immutable?: boolean;
|
|
1234
|
-
/** Must be provided on create (non-null). */
|
|
1235
|
-
required?: boolean;
|
|
1236
|
-
/** Default value if not provided on create. */
|
|
1237
|
-
default?: unknown;
|
|
1238
|
-
/** Auto-set ISO timestamp when the named field changes (optionally to a specific value). */
|
|
1239
|
-
timestampTrigger?: {
|
|
1240
|
-
field: string;
|
|
1241
|
-
value?: unknown;
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1275
|
+
|
|
1244
1276
|
interface ResolvedColumn {
|
|
1245
1277
|
id: string;
|
|
1246
1278
|
name: string;
|
|
@@ -1264,41 +1296,6 @@ declare function rowToData(row: Record<string, unknown>, columns: ResolvedColumn
|
|
|
1264
1296
|
declare function dataToColumnValues(data: Record<string, unknown>, columns: ResolvedColumn[]): Record<string, unknown>;
|
|
1265
1297
|
declare function coerceValue(value: unknown, storage: 'number' | 'text', interpretation: ColumnInterpretation): unknown;
|
|
1266
1298
|
declare function buildTableSelect(collectionName: string, columns: ResolvedColumn[]): string;
|
|
1267
|
-
type PermissionLevel = boolean | 'own' | 'unclaimed-or-own' | 'collaborator' | 'team' | 'access' | 'published' | 'shared';
|
|
1268
|
-
interface RolePermissions {
|
|
1269
|
-
read: PermissionLevel;
|
|
1270
|
-
create: boolean;
|
|
1271
|
-
update: PermissionLevel;
|
|
1272
|
-
delete: PermissionLevel;
|
|
1273
|
-
/** If set, only these columns can be updated by this role. */
|
|
1274
|
-
writableFields?: string[];
|
|
1275
|
-
}
|
|
1276
|
-
interface CollectionSchema {
|
|
1277
|
-
name: string;
|
|
1278
|
-
/** Column definitions — every collection is stored in a typed SQL table. */
|
|
1279
|
-
columns: ColumnDefinition[];
|
|
1280
|
-
/** Composite uniqueness constraint (e.g., ['userId', 'taskId']). */
|
|
1281
|
-
uniqueOn?: string[];
|
|
1282
|
-
/** Column name used for ownership checks (default: `_created_by`). */
|
|
1283
|
-
ownerField?: string;
|
|
1284
|
-
/** Column containing JSON array of collaborator user IDs. */
|
|
1285
|
-
collaboratorsField?: string;
|
|
1286
|
-
/** Column containing team ID for team-based access. */
|
|
1287
|
-
teamField?: string;
|
|
1288
|
-
/**
|
|
1289
|
-
* Column controlling per-record read visibility.
|
|
1290
|
-
* String: visible when `data[field] === 'public'`.
|
|
1291
|
-
* Object: visible when `data[field] === value`.
|
|
1292
|
-
*/
|
|
1293
|
-
visibilityField?: string | {
|
|
1294
|
-
field: string;
|
|
1295
|
-
value: unknown;
|
|
1296
|
-
};
|
|
1297
|
-
/** Permissions per role. Use '*' for a catch-all fallback. */
|
|
1298
|
-
permissions: Record<string, RolePermissions>;
|
|
1299
|
-
/** Default role for new users (only on 'users' collection). */
|
|
1300
|
-
defaultRole?: string;
|
|
1301
|
-
}
|
|
1302
1299
|
interface User {
|
|
1303
1300
|
id: string;
|
|
1304
1301
|
email: string;
|
|
@@ -1433,8 +1430,6 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1433
1430
|
private initPromise;
|
|
1434
1431
|
/** Yjs docs loaded in memory (key: collection:recordId:fieldName) */
|
|
1435
1432
|
private yjsDocs;
|
|
1436
|
-
/** Next Yjs client ID counter */
|
|
1437
|
-
private nextYjsClientId;
|
|
1438
1433
|
/** Owner user ID — gets admin role automatically */
|
|
1439
1434
|
private ownerUserId;
|
|
1440
1435
|
/** True until the first fetch() completes — detects hibernation wake-up */
|
|
@@ -1449,7 +1444,7 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1449
1444
|
* The HTTP debug API (`/api/debug/*`) runs arbitrary SQL and role changes
|
|
1450
1445
|
* with no auth of its own, so it is gated here at the DO's single ingress.
|
|
1451
1446
|
* Off unless a deployment opts in with `ALLOW_DEBUG_ROUTES=true`
|
|
1452
|
-
* (`deepspace dev`/`test` set it automatically). Deployments holding shared
|
|
1447
|
+
* (`deepspace dev start`/`test run` set it automatically). Deployments holding shared
|
|
1453
1448
|
* data override this to always return false.
|
|
1454
1449
|
*/
|
|
1455
1450
|
protected get debugRoutesEnabled(): boolean;
|
|
@@ -1474,7 +1469,7 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1474
1469
|
protected onMessage(): void;
|
|
1475
1470
|
webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
|
|
1476
1471
|
webSocketClose(ws: WebSocket, code: number, reason: string): Promise<void>;
|
|
1477
|
-
webSocketError(
|
|
1472
|
+
webSocketError(_ws: WebSocket, error: unknown): Promise<void>;
|
|
1478
1473
|
private handleRecordMessage;
|
|
1479
1474
|
private handleListSchemas;
|
|
1480
1475
|
private createHandlerContext;
|
|
@@ -1519,7 +1514,7 @@ declare class YjsRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1519
1514
|
type: string;
|
|
1520
1515
|
[key: string]: unknown;
|
|
1521
1516
|
}): void;
|
|
1522
|
-
protected onBinaryMessage(ws: WebSocket,
|
|
1517
|
+
protected onBinaryMessage(ws: WebSocket, _user: UserAttachment, data: ArrayBuffer): void;
|
|
1523
1518
|
protected onDisconnect(ws: WebSocket, _user: UserAttachment): void;
|
|
1524
1519
|
private handleSync;
|
|
1525
1520
|
private handleAwareness;
|
|
@@ -1586,7 +1581,7 @@ declare abstract class GameRoom<E = Record<string, unknown>> extends BaseRoom<E>
|
|
|
1586
1581
|
type: string;
|
|
1587
1582
|
[key: string]: unknown;
|
|
1588
1583
|
}): Promise<void>;
|
|
1589
|
-
protected onDisconnect(
|
|
1584
|
+
protected onDisconnect(_ws: WebSocket, user: UserAttachment): void;
|
|
1590
1585
|
protected onAlarm(): Promise<void>;
|
|
1591
1586
|
private checkAutoStart;
|
|
1592
1587
|
private startGame;
|
|
@@ -1686,7 +1681,7 @@ declare class CanvasRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1686
1681
|
type: string;
|
|
1687
1682
|
[key: string]: unknown;
|
|
1688
1683
|
}): Promise<void>;
|
|
1689
|
-
protected onDisconnect(
|
|
1684
|
+
protected onDisconnect(_ws: WebSocket, user: UserAttachment): void;
|
|
1690
1685
|
private pushUndo;
|
|
1691
1686
|
private clearRedo;
|
|
1692
1687
|
private handleUndo;
|
|
@@ -1740,6 +1735,19 @@ declare class PresenceRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1740
1735
|
protected onDisconnect(ws: WebSocket, user: UserAttachment): void;
|
|
1741
1736
|
}
|
|
1742
1737
|
|
|
1738
|
+
/** Pure validation and evaluation for CronRoom schedules. */
|
|
1739
|
+
interface CronTask {
|
|
1740
|
+
name: string;
|
|
1741
|
+
/** Interval in minutes (interval mode) — mutually exclusive with `schedule`. */
|
|
1742
|
+
intervalMinutes?: number;
|
|
1743
|
+
/** 5-field cron expression (cron mode) — requires `timezone`. */
|
|
1744
|
+
schedule?: string;
|
|
1745
|
+
/** IANA timezone string (e.g. "America/New_York"). Required with `schedule`. */
|
|
1746
|
+
timezone?: string;
|
|
1747
|
+
/** Whether the task starts paused. */
|
|
1748
|
+
paused?: boolean;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1743
1751
|
/**
|
|
1744
1752
|
* CronRoom — Per-app scheduled task execution Durable Object.
|
|
1745
1753
|
*
|
|
@@ -1758,17 +1766,6 @@ declare class PresenceRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1758
1766
|
* Message types: cron.*
|
|
1759
1767
|
*/
|
|
1760
1768
|
|
|
1761
|
-
interface CronTask {
|
|
1762
|
-
name: string;
|
|
1763
|
-
/** Interval in minutes (interval mode) — mutually exclusive with `schedule`. */
|
|
1764
|
-
intervalMinutes?: number;
|
|
1765
|
-
/** 5-field cron expression (cron mode) — requires `timezone`. */
|
|
1766
|
-
schedule?: string;
|
|
1767
|
-
/** IANA timezone string (e.g. "America/New_York"). Required with `schedule`. */
|
|
1768
|
-
timezone?: string;
|
|
1769
|
-
/** Whether the task starts paused. */
|
|
1770
|
-
paused?: boolean;
|
|
1771
|
-
}
|
|
1772
1769
|
interface CronRoomConfig {
|
|
1773
1770
|
tasks: CronTask[];
|
|
1774
1771
|
}
|
|
@@ -2523,6 +2520,8 @@ declare class Awareness {
|
|
|
2523
2520
|
* Remove awareness states for disconnected clients
|
|
2524
2521
|
*/
|
|
2525
2522
|
removeStates(clientIds: number[]): void;
|
|
2523
|
+
/** Release all state and listeners owned by this awareness instance. */
|
|
2524
|
+
destroy(): void;
|
|
2526
2525
|
}
|
|
2527
2526
|
/**
|
|
2528
2527
|
* Encode a full awareness message
|
|
@@ -2541,11 +2540,99 @@ declare function handleAwarenessMessage(awareness: Awareness, data: Uint8Array):
|
|
|
2541
2540
|
*/
|
|
2542
2541
|
declare function getMessageType(data: Uint8Array): number;
|
|
2543
2542
|
|
|
2543
|
+
/**
|
|
2544
|
+
* Wildcard-aware CORS origin matching for the platform workers.
|
|
2545
|
+
*
|
|
2546
|
+
* Hono's array form of `cors({ origin: [...] })` is an exact `includes()` — it
|
|
2547
|
+
* never expands `*`. Every worker that listed `https://*.app.space` or
|
|
2548
|
+
* `http://localhost:*` in an array had a dead entry: the wildcard rows matched
|
|
2549
|
+
* nothing, silently narrowing the effective CORS surface to the literal
|
|
2550
|
+
* entries. This helper is the single implementation both the api and deploy
|
|
2551
|
+
* workers pass to Hono's function-form `origin`, so the pattern semantics
|
|
2552
|
+
* can't drift between them.
|
|
2553
|
+
*
|
|
2554
|
+
* `*` stands for exactly one host label or a port: it never crosses a dot or
|
|
2555
|
+
* a slash, so `https://*.app.space` matches `https://x.app.space` but neither
|
|
2556
|
+
* `https://a.b.app.space` nor `https://x.app.space.evil.com`.
|
|
2557
|
+
*/
|
|
2558
|
+
declare function matchOrigin(origin: string, patterns: string[]): string | null;
|
|
2559
|
+
/**
|
|
2560
|
+
* The platform's standard browser-origin allow-list, derived from the
|
|
2561
|
+
* environment's apexes so a second constellation (staging) trusts its own
|
|
2562
|
+
* hosts and only its own. Both values are explicit deployment-plane config.
|
|
2563
|
+
* Dedupes for environments that serve both roles from one apex.
|
|
2564
|
+
*/
|
|
2565
|
+
declare function platformCorsPatterns(env: {
|
|
2566
|
+
APP_DOMAIN: string;
|
|
2567
|
+
PLATFORM_DOMAIN: string;
|
|
2568
|
+
}): string[];
|
|
2569
|
+
|
|
2570
|
+
/**
|
|
2571
|
+
* Deployed-app quota defaults — the ONE copy.
|
|
2572
|
+
*
|
|
2573
|
+
* Two workers use these numbers for different jobs: the deploy worker
|
|
2574
|
+
* ENFORCES them at registration time, the api worker DISPLAYS them via
|
|
2575
|
+
* GET /api/plan-limits. They used to be independent literal sets (plus the
|
|
2576
|
+
* same numbers again in six wrangler [vars] blocks as overrides) and had
|
|
2577
|
+
* already diverged once — the display copy was missing the admin tier
|
|
2578
|
+
* entirely. The env vars remain the per-plane override mechanism; only the
|
|
2579
|
+
* fallbacks live here.
|
|
2580
|
+
*/
|
|
2581
|
+
declare const DEPLOYED_APPS_DEFAULTS: {
|
|
2582
|
+
readonly free: 1;
|
|
2583
|
+
readonly starter: 4;
|
|
2584
|
+
readonly premium: 10;
|
|
2585
|
+
readonly admin: 100;
|
|
2586
|
+
};
|
|
2587
|
+
/** Parse a quota env override; anything non-integer/negative = fallback. */
|
|
2588
|
+
declare function parseQuotaLimit(raw: string | undefined, fallback: number): number;
|
|
2589
|
+
|
|
2590
|
+
/**
|
|
2591
|
+
* The ONE registry client. Every platform worker reaches the app-registry
|
|
2592
|
+
* Durable Object (hosted by the deploy worker, singleton `v1:global`) through
|
|
2593
|
+
* a cross-script REGISTRY binding — and before this module, each of the five
|
|
2594
|
+
* workers hand-rolled its own copy of the same mechanics: the instance name
|
|
2595
|
+
* appeared in 6 places, the `https://registry/` URL in 6, `APP_ID_RE` in 5,
|
|
2596
|
+
* and `RegistryClientError` + `registryErrorJson` existed byte-identical in
|
|
2597
|
+
* two workers. Copies that must agree and nothing enforcing it.
|
|
2598
|
+
*
|
|
2599
|
+
* This module owns the MECHANICS: instance name, stub lookup, the wire call,
|
|
2600
|
+
* the error type, and the standard route mapping. Each worker still declares
|
|
2601
|
+
* its own typed convenience wrapper listing only the actions it uses — that
|
|
2602
|
+
* subset is genuinely per-worker; the plumbing is not.
|
|
2603
|
+
*/
|
|
2604
|
+
/** The singleton registry instance — one DO holds every app/route/collaborator. */
|
|
2605
|
+
declare const REGISTRY_INSTANCE = "v1:global";
|
|
2606
|
+
/** App id shape: a ULID-minted `app_…` id, or a legacy name-as-id. */
|
|
2607
|
+
declare const APP_ID_RE: RegExp;
|
|
2608
|
+
/** ONLY a ULID-minted id — surfaces that must not accept a legacy name. */
|
|
2609
|
+
declare const STRICT_APP_ID_RE: RegExp;
|
|
2610
|
+
declare class RegistryClientError extends Error {
|
|
2611
|
+
readonly code: string;
|
|
2612
|
+
readonly status: number;
|
|
2613
|
+
constructor(message: string, code: string, status: number);
|
|
2614
|
+
}
|
|
2615
|
+
declare function registryStub(ns: DurableObjectNamespace): DurableObjectStub;
|
|
2616
|
+
/**
|
|
2617
|
+
* One registry action over the wire. Non-2xx answers throw
|
|
2618
|
+
* {@link RegistryClientError} carrying the DO's structured `code` (or
|
|
2619
|
+
* `'error'` for a transport-shaped body) — callers distinguish a registry-
|
|
2620
|
+
* REPORTED miss (`code === 'not_found'`) from an outage by that code, never
|
|
2621
|
+
* by treating every throw as "not found".
|
|
2622
|
+
*/
|
|
2623
|
+
declare function callRegistry<T>(stub: DurableObjectStub, body: {
|
|
2624
|
+
action: string;
|
|
2625
|
+
} & Record<string, unknown>): Promise<T>;
|
|
2626
|
+
/** Standard mapping of a registry failure onto a route response. */
|
|
2627
|
+
declare function registryErrorJson(c: {
|
|
2628
|
+
json: (body: unknown, status?: number) => Response;
|
|
2629
|
+
}, err: unknown): Response;
|
|
2630
|
+
|
|
2544
2631
|
/**
|
|
2545
2632
|
* Tools API Types and Definitions
|
|
2546
2633
|
*
|
|
2547
2634
|
* MCP-like interface for agent tool calls.
|
|
2548
|
-
* Built-in tools for
|
|
2635
|
+
* Built-in tools for records, schemas, users, and Yjs documents.
|
|
2549
2636
|
*/
|
|
2550
2637
|
interface ToolSchema {
|
|
2551
2638
|
name: string;
|
|
@@ -2593,7 +2680,7 @@ declare const DEFAULT_QUERY_LIMIT = 50;
|
|
|
2593
2680
|
*/
|
|
2594
2681
|
declare function applyAiToolDefaults(toolName: string, params: Record<string, unknown>): Record<string, unknown>;
|
|
2595
2682
|
/**
|
|
2596
|
-
* Built-in tool definitions for
|
|
2683
|
+
* Built-in tool definitions for record, schema, user, and Yjs operations.
|
|
2597
2684
|
*/
|
|
2598
2685
|
declare const BUILT_IN_TOOLS: ToolSchema[];
|
|
2599
2686
|
|
|
@@ -2789,7 +2876,7 @@ type ActionHandler<TEnv = Record<string, unknown>> = (ctx: ActionContext<TEnv>)
|
|
|
2789
2876
|
* in deployed apps.
|
|
2790
2877
|
*
|
|
2791
2878
|
* 2. **HTTPS URL** (`env.API_WORKER_URL` / `env.PLATFORM_WORKER_URL`) — the
|
|
2792
|
-
* fallback used in local development. `deepspace dev` writes these
|
|
2879
|
+
* fallback used in local development. `deepspace dev start` writes these
|
|
2793
2880
|
* into `.dev.vars`, which `wrangler dev` exposes as env vars. Service
|
|
2794
2881
|
* bindings don't work cross-process under `wrangler dev` for SDK apps,
|
|
2795
2882
|
* so the URL is the only working path in dev.
|
|
@@ -2807,7 +2894,7 @@ type ActionHandler<TEnv = Record<string, unknown>> = (ctx: ActionContext<TEnv>)
|
|
|
2807
2894
|
* History: a previous in-tree helper folded the binding/URL fallback into
|
|
2808
2895
|
* the AI module's `resolveTransport`. Inline call sites in the starter
|
|
2809
2896
|
* template (integrations, files, debug) used `c.env.X.fetch(...)` directly,
|
|
2810
|
-
* which broke `npx deepspace dev` for any app calling those routes — the
|
|
2897
|
+
* which broke `npx deepspace dev start` for any app calling those routes — the
|
|
2811
2898
|
* binding is undefined locally, so the fetch threw. These helpers
|
|
2812
2899
|
* standardize on the same shape `resolveTransport` had, so every upstream
|
|
2813
2900
|
* call works in both dev and prod.
|
|
@@ -2928,13 +3015,13 @@ declare function buildCronContext(env: CronEnv, ownerUserId: string, roomId?: st
|
|
|
2928
3015
|
* - Service binding `env.API_WORKER` (Cloudflare Fetcher) — preferred in
|
|
2929
3016
|
* production if the app has declared the binding in wrangler.toml.
|
|
2930
3017
|
* - HTTPS URL `env.API_WORKER_URL` — used in local dev and in production
|
|
2931
|
-
* for apps that don't declare the binding. `deepspace dev` writes this
|
|
3018
|
+
* for apps that don't declare the binding. `deepspace dev start` writes this
|
|
2932
3019
|
* into `.dev.vars` automatically.
|
|
2933
3020
|
*
|
|
2934
3021
|
* Auth is automatic by default:
|
|
2935
3022
|
* - For server-side autonomous calls (cron, DO alarms, background agents),
|
|
2936
3023
|
* the helper reads the long-lived `env.APP_OWNER_JWT` minted at deploy
|
|
2937
|
-
* time (or by `deepspace dev` in local development) and uses it for the
|
|
3024
|
+
* time (or by `deepspace dev start` in local development) and uses it for the
|
|
2938
3025
|
* proxy auth header. The owner is billed automatically via the JWT sub.
|
|
2939
3026
|
* - For user-initiated calls (e.g. an `/api/ai/chat` route handling a
|
|
2940
3027
|
* browser request), pass `options.authToken` explicitly with the user's
|
|
@@ -2961,7 +3048,7 @@ type DeepSpaceModelFactory = (modelId: string) => LanguageModel;
|
|
|
2961
3048
|
type Provider = 'anthropic' | 'openai' | 'cerebras';
|
|
2962
3049
|
interface DeepSpaceAIEnv extends ApiWorkerEnv {
|
|
2963
3050
|
/**
|
|
2964
|
-
* Long-lived owner-scoped JWT minted at deploy time (or by `deepspace dev`).
|
|
3051
|
+
* Long-lived owner-scoped JWT minted at deploy time (or by `deepspace dev start`).
|
|
2965
3052
|
* Used as the default proxy auth token when `options.authToken` is absent.
|
|
2966
3053
|
* Bills the app owner.
|
|
2967
3054
|
*/
|
|
@@ -3038,10 +3125,9 @@ declare function composioTools(env: ApiWorkerEnv, options: ComposioToolsOptions)
|
|
|
3038
3125
|
* own bundle. The platform holds the binding; consumers call this
|
|
3039
3126
|
* helper to get PNG bytes for a URL.
|
|
3040
3127
|
*
|
|
3041
|
-
* The platform enforces
|
|
3042
|
-
*
|
|
3043
|
-
*
|
|
3044
|
-
* and surface their own fallback UX.
|
|
3128
|
+
* The platform enforces HTTPS, a DeepSpace host allowlist, a per-app rate
|
|
3129
|
+
* limit, and one fixed viewport-only capture profile. Returns `null` on any
|
|
3130
|
+
* non-2xx — callers should treat that as "no preview available".
|
|
3045
3131
|
*
|
|
3046
3132
|
* Auth is the same HMAC-of-appId pattern `/internal/files` uses:
|
|
3047
3133
|
* x-app-identity-token = hmac(PLATFORM_IDENTITY_SECRET, DEEPSPACE_APP_ID)
|
|
@@ -3051,16 +3137,6 @@ declare function composioTools(env: ApiWorkerEnv, options: ComposioToolsOptions)
|
|
|
3051
3137
|
* so this helper is a thin wrapper — no extra secrets to manage.
|
|
3052
3138
|
*/
|
|
3053
3139
|
|
|
3054
|
-
interface ScreenshotOptions {
|
|
3055
|
-
url: string;
|
|
3056
|
-
viewport?: {
|
|
3057
|
-
width: number;
|
|
3058
|
-
height: number;
|
|
3059
|
-
};
|
|
3060
|
-
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
|
|
3061
|
-
timeoutMs?: number;
|
|
3062
|
-
fullPage?: boolean;
|
|
3063
|
-
}
|
|
3064
3140
|
interface ScreenshotEnv extends PlatformWorkerEnv {
|
|
3065
3141
|
/** Immutable app id — the identity the platform verifies (HMAC input). */
|
|
3066
3142
|
DEEPSPACE_APP_ID: string;
|
|
@@ -3074,14 +3150,13 @@ interface ScreenshotResult {
|
|
|
3074
3150
|
contentType: string;
|
|
3075
3151
|
}
|
|
3076
3152
|
/**
|
|
3077
|
-
* Capture a screenshot of `
|
|
3153
|
+
* Capture a screenshot of `url` and return the PNG bytes.
|
|
3078
3154
|
*
|
|
3079
3155
|
* Returns null on capture failure (target unreachable, timeout, BR
|
|
3080
|
-
* binding misconfigured platform-side). The platform
|
|
3081
|
-
*
|
|
3082
|
-
* and surface their own UX fallback.
|
|
3156
|
+
* binding misconfigured platform-side). The platform logs a generic failure
|
|
3157
|
+
* without target details; callers should surface their own fallback UX.
|
|
3083
3158
|
*/
|
|
3084
|
-
declare function captureScreenshot(env: ScreenshotEnv,
|
|
3159
|
+
declare function captureScreenshot(env: ScreenshotEnv, url: string): Promise<ScreenshotResult | null>;
|
|
3085
3160
|
|
|
3086
3161
|
/**
|
|
3087
3162
|
* Chat context pipeline — keeps the per-request payload to the LLM bounded.
|
|
@@ -3225,23 +3300,8 @@ declare function makeDefaultSummarizer(env: DeepSpaceAIEnv, options?: {
|
|
|
3225
3300
|
* The tools API returns records as `{ recordId, data, createdAt, updatedAt }`
|
|
3226
3301
|
* envelopes; helpers below flatten them into ChatRow / ChatMessageRow.
|
|
3227
3302
|
*/
|
|
3228
|
-
/**
|
|
3229
|
-
* Canonical chat row.
|
|
3230
|
-
*
|
|
3231
|
-
* `recordId` is the primary identifier — same envelope shape as every
|
|
3232
|
-
* other DeepSpace data type (records.* tools, useQuery results, etc.).
|
|
3233
|
-
*
|
|
3234
|
-
* `id` is kept as a deprecated alias so existing callers don't break,
|
|
3235
|
-
* but every new caller should prefer `recordId`. Without this rename
|
|
3236
|
-
* an integrator who reads `chat.recordId` (the obvious thing given the
|
|
3237
|
-
* rest of the SDK) silently gets `undefined`, then ships code that
|
|
3238
|
-
* sends `{"chatId": undefined}` to `/api/ai/chat` and gets back a 400
|
|
3239
|
-
* with a misleading error.
|
|
3240
|
-
*/
|
|
3241
3303
|
type ChatRow = {
|
|
3242
3304
|
recordId: string;
|
|
3243
|
-
/** @deprecated Use `recordId`. Retained for backward compatibility. */
|
|
3244
|
-
id: string;
|
|
3245
3305
|
userId: string;
|
|
3246
3306
|
title: string;
|
|
3247
3307
|
model?: string;
|
|
@@ -3252,8 +3312,6 @@ type ChatRow = {
|
|
|
3252
3312
|
};
|
|
3253
3313
|
type ChatMessageRow = {
|
|
3254
3314
|
recordId: string;
|
|
3255
|
-
/** @deprecated Use `recordId`. Retained for backward compatibility. */
|
|
3256
|
-
id: string;
|
|
3257
3315
|
chatId: string;
|
|
3258
3316
|
userId: string;
|
|
3259
3317
|
role: 'user' | 'assistant' | 'system';
|
|
@@ -3568,7 +3626,7 @@ declare function decodeJwtPayload(token: string | null | undefined): TokenDebugI
|
|
|
3568
3626
|
/**
|
|
3569
3627
|
* Test-account identification, shared by every platform worker.
|
|
3570
3628
|
*
|
|
3571
|
-
* Test accounts (created via `deepspace test
|
|
3629
|
+
* Test accounts (created via `deepspace test accounts`) are real Better Auth
|
|
3572
3630
|
* users demarcated three ways, and a caller may present as any of them
|
|
3573
3631
|
* depending on where the check runs:
|
|
3574
3632
|
* - their email always ends with @deepspace.test (enforced at creation)
|
|
@@ -3629,8 +3687,184 @@ interface DeepSpaceAuthConfig {
|
|
|
3629
3687
|
emailAndPassword?: boolean;
|
|
3630
3688
|
/** Trusted origins for CORS */
|
|
3631
3689
|
trustedOrigins?: string[];
|
|
3690
|
+
/**
|
|
3691
|
+
* Called after a new user row is created (any flow: social OAuth callback,
|
|
3692
|
+
* email/password, server-side `auth.api.signUpEmail`). When the signup came
|
|
3693
|
+
* in over HTTP, `ctx.request` exposes the inbound request; some better-auth
|
|
3694
|
+
* entry points carry standalone `ctx.headers` instead of (or as well as) a
|
|
3695
|
+
* request, so both are forwarded. For server-side creations (`auth.api.*`
|
|
3696
|
+
* calls) an endpoint context usually still exists but may carry NEITHER —
|
|
3697
|
+
* guard every field.
|
|
3698
|
+
*
|
|
3699
|
+
* Better Auth awaits `user.create.after` hooks inline before the response
|
|
3700
|
+
* is sent, so keep this cheap (e.g. a single D1 write) and hand slow work
|
|
3701
|
+
* to `ctx.waitUntil` at the call site. Exceptions are caught and logged so
|
|
3702
|
+
* a failing observer can never break signup itself.
|
|
3703
|
+
*/
|
|
3704
|
+
onUserCreated?: (user: {
|
|
3705
|
+
id: string;
|
|
3706
|
+
email: string;
|
|
3707
|
+
name: string;
|
|
3708
|
+
}, ctx: {
|
|
3709
|
+
request?: Request;
|
|
3710
|
+
headers?: Headers;
|
|
3711
|
+
} | null) => Promise<void>;
|
|
3632
3712
|
}
|
|
3633
3713
|
declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.Auth<{
|
|
3714
|
+
databaseHooks: {
|
|
3715
|
+
user?: {
|
|
3716
|
+
create?: {
|
|
3717
|
+
before?: (user: better_auth.User & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3718
|
+
data: {
|
|
3719
|
+
id?: string | undefined;
|
|
3720
|
+
createdAt?: Date | undefined;
|
|
3721
|
+
updatedAt?: Date | undefined;
|
|
3722
|
+
email?: string | undefined;
|
|
3723
|
+
emailVerified?: boolean | undefined;
|
|
3724
|
+
name?: string | undefined;
|
|
3725
|
+
image?: string | null | undefined;
|
|
3726
|
+
} & Record<string, any>;
|
|
3727
|
+
}>;
|
|
3728
|
+
after?: (user: better_auth.User & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3729
|
+
};
|
|
3730
|
+
update?: {
|
|
3731
|
+
before?: (user: Partial<better_auth.User> & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3732
|
+
data: {
|
|
3733
|
+
[x: string]: any;
|
|
3734
|
+
id?: string | undefined;
|
|
3735
|
+
createdAt?: Date | undefined;
|
|
3736
|
+
updatedAt?: Date | undefined;
|
|
3737
|
+
email?: string | undefined;
|
|
3738
|
+
emailVerified?: boolean | undefined;
|
|
3739
|
+
name?: string | undefined;
|
|
3740
|
+
image?: string | null | undefined;
|
|
3741
|
+
};
|
|
3742
|
+
}>;
|
|
3743
|
+
after?: (user: better_auth.User & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3744
|
+
};
|
|
3745
|
+
delete?: {
|
|
3746
|
+
before?: (user: better_auth.User & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void>;
|
|
3747
|
+
after?: (user: better_auth.User & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3748
|
+
};
|
|
3749
|
+
};
|
|
3750
|
+
session?: {
|
|
3751
|
+
create?: {
|
|
3752
|
+
before?: (session: better_auth.Session & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3753
|
+
data: {
|
|
3754
|
+
id?: string | undefined;
|
|
3755
|
+
createdAt?: Date | undefined;
|
|
3756
|
+
updatedAt?: Date | undefined;
|
|
3757
|
+
userId?: string | undefined;
|
|
3758
|
+
expiresAt?: Date | undefined;
|
|
3759
|
+
token?: string | undefined;
|
|
3760
|
+
ipAddress?: string | null | undefined;
|
|
3761
|
+
userAgent?: string | null | undefined;
|
|
3762
|
+
} & Record<string, any>;
|
|
3763
|
+
}>;
|
|
3764
|
+
after?: (session: better_auth.Session & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3765
|
+
};
|
|
3766
|
+
update?: {
|
|
3767
|
+
before?: (session: Partial<better_auth.Session> & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3768
|
+
data: {
|
|
3769
|
+
[x: string]: any;
|
|
3770
|
+
id?: string | undefined;
|
|
3771
|
+
createdAt?: Date | undefined;
|
|
3772
|
+
updatedAt?: Date | undefined;
|
|
3773
|
+
userId?: string | undefined;
|
|
3774
|
+
expiresAt?: Date | undefined;
|
|
3775
|
+
token?: string | undefined;
|
|
3776
|
+
ipAddress?: string | null | undefined;
|
|
3777
|
+
userAgent?: string | null | undefined;
|
|
3778
|
+
};
|
|
3779
|
+
}>;
|
|
3780
|
+
after?: (session: better_auth.Session & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3781
|
+
};
|
|
3782
|
+
delete?: {
|
|
3783
|
+
before?: (session: better_auth.Session & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void>;
|
|
3784
|
+
after?: (session: better_auth.Session & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3785
|
+
};
|
|
3786
|
+
};
|
|
3787
|
+
account?: {
|
|
3788
|
+
create?: {
|
|
3789
|
+
before?: (account: better_auth.Account, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3790
|
+
data: {
|
|
3791
|
+
id?: string | undefined;
|
|
3792
|
+
createdAt?: Date | undefined;
|
|
3793
|
+
updatedAt?: Date | undefined;
|
|
3794
|
+
providerId?: string | undefined;
|
|
3795
|
+
accountId?: string | undefined;
|
|
3796
|
+
userId?: string | undefined;
|
|
3797
|
+
accessToken?: string | null | undefined;
|
|
3798
|
+
refreshToken?: string | null | undefined;
|
|
3799
|
+
idToken?: string | null | undefined;
|
|
3800
|
+
accessTokenExpiresAt?: Date | null | undefined;
|
|
3801
|
+
refreshTokenExpiresAt?: Date | null | undefined;
|
|
3802
|
+
scope?: string | null | undefined;
|
|
3803
|
+
password?: string | null | undefined;
|
|
3804
|
+
} & Record<string, any>;
|
|
3805
|
+
}>;
|
|
3806
|
+
after?: (account: better_auth.Account, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3807
|
+
};
|
|
3808
|
+
update?: {
|
|
3809
|
+
before?: (account: Partial<better_auth.Account> & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3810
|
+
data: {
|
|
3811
|
+
[x: string]: any;
|
|
3812
|
+
id?: string | undefined;
|
|
3813
|
+
createdAt?: Date | undefined;
|
|
3814
|
+
updatedAt?: Date | undefined;
|
|
3815
|
+
providerId?: string | undefined;
|
|
3816
|
+
accountId?: string | undefined;
|
|
3817
|
+
userId?: string | undefined;
|
|
3818
|
+
accessToken?: string | null | undefined;
|
|
3819
|
+
refreshToken?: string | null | undefined;
|
|
3820
|
+
idToken?: string | null | undefined;
|
|
3821
|
+
accessTokenExpiresAt?: Date | null | undefined;
|
|
3822
|
+
refreshTokenExpiresAt?: Date | null | undefined;
|
|
3823
|
+
scope?: string | null | undefined;
|
|
3824
|
+
password?: string | null | undefined;
|
|
3825
|
+
};
|
|
3826
|
+
}>;
|
|
3827
|
+
after?: (account: better_auth.Account & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3828
|
+
};
|
|
3829
|
+
delete?: {
|
|
3830
|
+
before?: (account: better_auth.Account & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void>;
|
|
3831
|
+
after?: (account: better_auth.Account & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3832
|
+
};
|
|
3833
|
+
};
|
|
3834
|
+
verification?: {
|
|
3835
|
+
create?: {
|
|
3836
|
+
before?: (verification: better_auth.Verification & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3837
|
+
data: {
|
|
3838
|
+
id?: string | undefined;
|
|
3839
|
+
createdAt?: Date | undefined;
|
|
3840
|
+
updatedAt?: Date | undefined;
|
|
3841
|
+
value?: string | undefined;
|
|
3842
|
+
expiresAt?: Date | undefined;
|
|
3843
|
+
identifier?: string | undefined;
|
|
3844
|
+
} & Record<string, any>;
|
|
3845
|
+
}>;
|
|
3846
|
+
after?: (verification: better_auth.Verification & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3847
|
+
};
|
|
3848
|
+
update?: {
|
|
3849
|
+
before?: (verification: Partial<better_auth.Verification> & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void | {
|
|
3850
|
+
data: {
|
|
3851
|
+
[x: string]: any;
|
|
3852
|
+
id?: string | undefined;
|
|
3853
|
+
createdAt?: Date | undefined;
|
|
3854
|
+
updatedAt?: Date | undefined;
|
|
3855
|
+
value?: string | undefined;
|
|
3856
|
+
expiresAt?: Date | undefined;
|
|
3857
|
+
identifier?: string | undefined;
|
|
3858
|
+
};
|
|
3859
|
+
}>;
|
|
3860
|
+
after?: (verification: better_auth.Verification & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3861
|
+
};
|
|
3862
|
+
delete?: {
|
|
3863
|
+
before?: (verification: better_auth.Verification & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<boolean | void>;
|
|
3864
|
+
after?: (verification: better_auth.Verification & Record<string, unknown>, context: better_auth.GenericEndpointContext | null) => Promise<void>;
|
|
3865
|
+
};
|
|
3866
|
+
};
|
|
3867
|
+
} | undefined;
|
|
3634
3868
|
plugins: [{
|
|
3635
3869
|
id: "organization";
|
|
3636
3870
|
version: string;
|
|
@@ -4483,6 +4717,10 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4483
4717
|
database: D1Database;
|
|
4484
4718
|
baseURL: string;
|
|
4485
4719
|
secret: string;
|
|
4720
|
+
session: {
|
|
4721
|
+
expiresIn: number;
|
|
4722
|
+
updateAge: number;
|
|
4723
|
+
};
|
|
4486
4724
|
emailAndPassword: {
|
|
4487
4725
|
enabled: boolean;
|
|
4488
4726
|
};
|
|
@@ -4498,4 +4736,148 @@ type DeepSpaceAuth = ReturnType<typeof createDeepSpaceAuth>;
|
|
|
4498
4736
|
/** Collections that bypass schema checks (permissive access) */
|
|
4499
4737
|
declare const SYSTEM_COLLECTIONS: Set<string>;
|
|
4500
4738
|
|
|
4501
|
-
|
|
4739
|
+
/**
|
|
4740
|
+
* Client-error ingestion route (opt-in) — the Worker half of client-side
|
|
4741
|
+
* error reporting.
|
|
4742
|
+
*
|
|
4743
|
+
* Mount it in your app Worker with a single line:
|
|
4744
|
+
*
|
|
4745
|
+
* import { registerClientErrorRoute } from 'deepspace/worker'
|
|
4746
|
+
* registerClientErrorRoute(app) // BEFORE the app.all('/_deepspace/*') proxy
|
|
4747
|
+
*
|
|
4748
|
+
* Then, in the browser, `installClientErrorReporter()` (from 'deepspace')
|
|
4749
|
+
* forwards uncaught errors here. The handler runs in the app's OWN Worker, so
|
|
4750
|
+
* the `console.error` it emits is tagged by Cloudflare with this app's id —
|
|
4751
|
+
* meaning a browser can only ever write to its own app's log stream, never
|
|
4752
|
+
* another tenant's or the platform's. Reports then surface in `deepspace logs`
|
|
4753
|
+
* (and the dashboard) tagged `CLIENT`.
|
|
4754
|
+
*
|
|
4755
|
+
* Anonymous by design (logged-out visitors hit client errors too), so the
|
|
4756
|
+
* defenses are size caps (normalizeClientErrorReport) + a best-effort
|
|
4757
|
+
* per-isolate throttle. It never blocks the page: it returns 204 and swallows
|
|
4758
|
+
* work quickly.
|
|
4759
|
+
*/
|
|
4760
|
+
|
|
4761
|
+
/**
|
|
4762
|
+
* Handle one client-error report. Framework-agnostic — pass a raw `Request`.
|
|
4763
|
+
* Returns 204 on success, 400 on a malformed/empty body, 429 when throttled.
|
|
4764
|
+
*/
|
|
4765
|
+
declare function handleClientErrorReport(request: Request): Promise<Response>;
|
|
4766
|
+
/**
|
|
4767
|
+
* Register `POST /_deepspace/client-errors` on your Hono app. Mount it BEFORE
|
|
4768
|
+
* the `app.all('/_deepspace/*')` proxy so the specific route wins the match.
|
|
4769
|
+
*/
|
|
4770
|
+
declare function registerClientErrorRoute(app: Hono<any, any, any>): void;
|
|
4771
|
+
|
|
4772
|
+
/**
|
|
4773
|
+
* Client-side error reporting — shared contract.
|
|
4774
|
+
*
|
|
4775
|
+
* Browser JS errors never invoke the app's Worker, so they never reach
|
|
4776
|
+
* Workers Logs and are invisible to `deepspace logs`. The opt-in reporter
|
|
4777
|
+
* (`installClientErrorReporter`, client entry) forwards them to the app's own
|
|
4778
|
+
* Worker via `registerClientErrorRoute` (worker entry), which `console.error`s
|
|
4779
|
+
* a marker-prefixed envelope. The platform log reader recognises the marker
|
|
4780
|
+
* and tags the event `source: 'client'`.
|
|
4781
|
+
*
|
|
4782
|
+
* This module is isomorphic — no DOM, no Hono — so both halves import the
|
|
4783
|
+
* exact same marker, caps, and normaliser and can never drift.
|
|
4784
|
+
*/
|
|
4785
|
+
/**
|
|
4786
|
+
* Prefix the Worker route prepends before JSON-stringifying a report into a
|
|
4787
|
+
* single `console.error` line. The platform mapper
|
|
4788
|
+
* (platform/deploy-worker/src/lib/workers-logs.ts) detects this prefix to set
|
|
4789
|
+
* `source: 'client'`. Deliberately distinctive so an ordinary app log is
|
|
4790
|
+
* vanishingly unlikely to collide. The marker is added SERVER-SIDE by the app
|
|
4791
|
+
* Worker — a browser cannot forge it onto a genuine server log.
|
|
4792
|
+
*
|
|
4793
|
+
* The platform copy is kept in sync by a drift test; if you change this
|
|
4794
|
+
* string, that test fails until the platform const matches.
|
|
4795
|
+
*/
|
|
4796
|
+
declare const CLIENT_LOG_MARKER = "[deepspace:client-error]";
|
|
4797
|
+
type ClientErrorKind = 'error' | 'unhandledrejection' | 'react';
|
|
4798
|
+
/** A sanitized, capped browser-error report — the wire + log-line payload. */
|
|
4799
|
+
interface ClientErrorReport {
|
|
4800
|
+
kind: ClientErrorKind;
|
|
4801
|
+
message: string;
|
|
4802
|
+
name?: string;
|
|
4803
|
+
stack?: string;
|
|
4804
|
+
/** Page URL where it fired (href or the script filename). */
|
|
4805
|
+
url?: string;
|
|
4806
|
+
line?: number;
|
|
4807
|
+
col?: number;
|
|
4808
|
+
}
|
|
4809
|
+
|
|
4810
|
+
/**
|
|
4811
|
+
* `deepspace logs` wire DTO — the single source of truth for the whitelisted
|
|
4812
|
+
* shape the platform telemetry reader emits and every consumer reads.
|
|
4813
|
+
*
|
|
4814
|
+
* The producer is `platform/deploy-worker/src/lib/workers-logs.ts` (which
|
|
4815
|
+
* rebuilds each event field-by-field from a raw Cloudflare row — see the
|
|
4816
|
+
* security invariant there). The consumers are the CLI tail
|
|
4817
|
+
* (`cli/commands/logs.ts`), the dashboard Logs panel
|
|
4818
|
+
* (`apps/dashboard/src/lib/apps.ts`), and the e2e whitelist assertion
|
|
4819
|
+
* (`tests/e2e/tests/logs.spec.ts`). This module used to be hand-mirrored in
|
|
4820
|
+
* all four places; `source` was added to three of them and missed in the
|
|
4821
|
+
* e2e whitelist, so it now lives here once and they import it.
|
|
4822
|
+
*
|
|
4823
|
+
* Isomorphic — no DOM, no Hono, no platform types — so it re-exports cleanly
|
|
4824
|
+
* from both `deepspace` (client) and `deepspace/worker` and is safe to import
|
|
4825
|
+
* from the private deploy-worker.
|
|
4826
|
+
*/
|
|
4827
|
+
declare const LOG_LEVELS: readonly ["debug", "log", "info", "warn", "error"];
|
|
4828
|
+
type LogLevel = (typeof LOG_LEVELS)[number];
|
|
4829
|
+
/** One log / request / exception event, rebuilt field-by-field from a CF row. */
|
|
4830
|
+
interface AppLogEvent {
|
|
4831
|
+
/** `$metadata.id` — unique per event; the client's dedupe key. */
|
|
4832
|
+
id: string;
|
|
4833
|
+
/** Unix ms. */
|
|
4834
|
+
timestamp: number;
|
|
4835
|
+
level: LogLevel;
|
|
4836
|
+
eventType: 'log' | 'request' | 'exception' | 'other';
|
|
4837
|
+
message: string;
|
|
4838
|
+
/**
|
|
4839
|
+
* Present (= `'client'`) only for a browser-forwarded error the app's own
|
|
4840
|
+
* Worker re-logged via `registerClientErrorRoute`. Absent means the log was
|
|
4841
|
+
* emitted server-side — there is no explicit `'server'` value, so consumers
|
|
4842
|
+
* branch on `source === 'client'`, never on a truthy/other check.
|
|
4843
|
+
*/
|
|
4844
|
+
source?: 'client';
|
|
4845
|
+
/** Invocation outcome (`ok`, `exception`, `exceededCpu`, …) when present. */
|
|
4846
|
+
outcome?: string;
|
|
4847
|
+
request?: {
|
|
4848
|
+
method: string;
|
|
4849
|
+
path: string;
|
|
4850
|
+
status?: number;
|
|
4851
|
+
};
|
|
4852
|
+
exception?: {
|
|
4853
|
+
name: string;
|
|
4854
|
+
message: string;
|
|
4855
|
+
stack?: string;
|
|
4856
|
+
};
|
|
4857
|
+
}
|
|
4858
|
+
interface AppLogsResponse {
|
|
4859
|
+
/** Ascending by timestamp (CF returns newest-first; the reader flips). */
|
|
4860
|
+
events: AppLogEvent[];
|
|
4861
|
+
/** Max event timestamp in ms — pass back as `since` to poll; null when empty. */
|
|
4862
|
+
cursor: number | null;
|
|
4863
|
+
/** True when the window returned `limit` events (older events were cut). */
|
|
4864
|
+
truncated: boolean;
|
|
4865
|
+
pollIntervalMs: number;
|
|
4866
|
+
}
|
|
4867
|
+
/**
|
|
4868
|
+
* Runtime tuple of every key a whitelisted `AppLogEvent` may carry — the
|
|
4869
|
+
* canonical whitelist the e2e suite mirrors when asserting no event leaks a key
|
|
4870
|
+
* outside this set. The two type-level assertions below fail compilation if
|
|
4871
|
+
* this tuple and the `AppLogEvent` interface disagree in either direction, so
|
|
4872
|
+
* adding an interface field forces a matching key here.
|
|
4873
|
+
*
|
|
4874
|
+
* NOTE: the e2e spec keeps its OWN copy of this set (it can't import the SDK —
|
|
4875
|
+
* `@deepspace/e2e` has no `deepspace` dependency), kept in step by a comment,
|
|
4876
|
+
* not by these compile-time guards. So this tuple hardens the code copies
|
|
4877
|
+
* (deploy-worker/CLI/dashboard, which import it), while the e2e mirror remains a
|
|
4878
|
+
* knowingly-accepted duplicate.
|
|
4879
|
+
*/
|
|
4880
|
+
declare const APP_LOG_EVENT_KEYS: readonly ["id", "timestamp", "level", "eventType", "message", "source", "outcome", "request", "exception"];
|
|
4881
|
+
type AppLogEventKey = (typeof APP_LOG_EVENT_KEYS)[number];
|
|
4882
|
+
|
|
4883
|
+
export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_ID_RE, APP_LOG_EVENT_KEYS, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppLogEvent, type AppLogEventKey, type AppLogsResponse, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, Awareness, type AwarenessState, type AwarenessStates, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, type BaseMessage, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CLIENT_LOG_MARKER, CONVERSATION_SCHEMAS, COST_RATES, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type ClientErrorKind, type ClientErrorReport, type ClientMessage, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConnectionAttachment, type ConvMemberData, type ConvMessageData, type ConvReactionData, type ConvReadCursorData, type ConvVoteData, type ConversationStateData, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEFAULT_CONTEXT_CONFIG, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DEPLOYED_APPS_DEFAULTS, DIRECTORY_SCHEMAS, type DOBindings, type DOManifest, type DOManifestEntry, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DirectoryCommunityData, type DirectoryConversationData, type DirectoryMembershipData, type DirectoryPostData, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, GLOBAL_DO_TYPES, GLOBAL_DO_TYPE_NAMES, type GameInput, GameRoom, type GameRoomConfig, type GetActionData, type GlobalDOType, type HandlerContext, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, LOG_LEVELS, type LogLevel, MESSAGES_SCHEMA, MSG, MSG_AWARENESS, MSG_SYNC, MSG_SYNC_STEP1, MSG_SYNC_STEP2, MSG_SYNC_UPDATE, MSG_YJS_AWARENESS, MSG_YJS_SYNC, type MessageHandlers, type MsgType, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlatformWorkerEnv, type Player, type PrefixResult, type PresencePeer, PresenceRoom, type ProtocolMessage, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, REGISTRY_INSTANCE, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_DEFAULT, RecordRoom, type RecordRoomConfig, RegistryClientError, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, STRICT_APP_ID_RE, SYSTEM_COLLECTIONS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type ServerMessage, type SharedConnection, type StoredRecord, type Summarizer, type SyncResult, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, USERS_COLUMNS, type User, type UserAttachment, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, capToolResultSize, captureScreenshot, checkFieldPermissions, clientBuild, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDecoder, createDeepSpaceAI, createDeepSpaceAuth, createEncoder, createScopedR2Handler, dataToColumnValues, decodeJwtPayload, deleteChatCascade, dispatch, encode, encodeAwarenessMessage, encodeSyncStep1, encodeSyncStep2, encodeUpdate, enqueueJob, getChat, getGlobalDOSchemas, getGlobalDOType, getMessageType, getRolePermissions, handleAwarenessMessage, handleClientErrorReport, handleSyncMessage, hasContent, isAutoProvision, isOwner, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, lintSchema, loadMessages, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, noopPermissionContext, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, readVarUint, readVarUint8Array, registerClientErrorRoute, registryErrorJson, registryStub, resolveAppName, resolveColumn, rowToData, runMigrations, serverBuild, timingSafeEqualHex, timingSafeEqualStrings, toUint8Array, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema, writeVarUint, writeVarUint8Array };
|