deepspace 0.15.0 → 0.17.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 +118 -0
- package/dist/cli.js +562 -237
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +26 -157
- package/dist/index.js +209 -331
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +28 -154
- package/dist/server.js +38 -426
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +44 -227
- package/dist/worker.js +39 -433
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -219,28 +219,24 @@ declare const UPLOAD_PART_BYTES: number;
|
|
|
219
219
|
*/
|
|
220
220
|
declare const MAX_UPLOAD_PARTS: number;
|
|
221
221
|
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
222
|
+
* The customer-visible storage schedule, in bytes, PER ACCOUNT — the total an
|
|
223
|
+
* owner's uploaded files may occupy across every app they own, not a budget
|
|
224
|
+
* each app gets separately. This is the number the billing page advertises.
|
|
224
225
|
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* - the app-files allocation, admitted by the shared files handler
|
|
228
|
-
* (`server/utils/scoped-r2-files.ts`)
|
|
226
|
+
* Admitted by the shared files handler (`server/utils/scoped-r2-files.ts`),
|
|
227
|
+
* which sums the owner's apps rather than the one being written to.
|
|
229
228
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* customer-visible "storage" number is the app-files allocation — the repo
|
|
233
|
-
* store is platform bookkeeping that degrades (drops rollback retention)
|
|
234
|
-
* rather than surfacing here.
|
|
229
|
+
* It deliberately does NOT govern the repo store — see
|
|
230
|
+
* `REPO_STORE_LIMIT_BYTES` below, and docs/platform/r2-storage.md.
|
|
235
231
|
*/
|
|
236
|
-
declare const
|
|
232
|
+
declare const ACCOUNT_STORAGE_LIMIT_BYTES: {
|
|
237
233
|
readonly test: 0;
|
|
238
234
|
readonly free: number;
|
|
239
235
|
readonly starter: number;
|
|
240
236
|
readonly premium: number;
|
|
241
237
|
readonly admin: number;
|
|
242
238
|
};
|
|
243
|
-
/** The storage limit for a billing tier; unknown or missing tiers get free. */
|
|
239
|
+
/** The account storage limit for a billing tier; unknown or missing tiers get free. */
|
|
244
240
|
declare function storageLimitForTier(tier: string | null | undefined): number;
|
|
245
241
|
/** The one storage-quota refusal sentence. `usedBytes` is net of any object
|
|
246
242
|
* the upload replaces, so an upsert is charged only for its growth. */
|
|
@@ -323,15 +319,26 @@ interface ScopedR2Config {
|
|
|
323
319
|
* applies.
|
|
324
320
|
*/
|
|
325
321
|
interface StorageAdmission {
|
|
326
|
-
/**
|
|
327
|
-
* (possibly deeper) scope prefix a request resolved to. */
|
|
322
|
+
/** This app's own prefix — the one the incoming write lands under. */
|
|
328
323
|
prefix: string;
|
|
329
324
|
/**
|
|
330
325
|
* Resolve the owner's limit in bytes. `null` means the lookup failed;
|
|
331
|
-
* writes then fail closed (503) rather than admitting unmetered storage
|
|
332
|
-
* mirroring the repo store's `StorageBillingUnavailableError`.
|
|
326
|
+
* writes then fail closed (503) rather than admitting unmetered storage.
|
|
333
327
|
*/
|
|
334
328
|
limitBytes: () => Promise<number | null>;
|
|
329
|
+
/**
|
|
330
|
+
* The OTHER app prefixes this owner's storage spans, if any.
|
|
331
|
+
*
|
|
332
|
+
* The limit is per ACCOUNT, not per app: an owner's allocation is the total
|
|
333
|
+
* across everything they own, so admission has to see the siblings too. `[]`
|
|
334
|
+
* for an owner with one app, which is the common case and costs exactly what
|
|
335
|
+
* it did when this was a per-app limit.
|
|
336
|
+
*
|
|
337
|
+
* Returning `null` means the owner's apps could not be enumerated. Like a
|
|
338
|
+
* failed limit lookup that fails the write closed rather than admitting a
|
|
339
|
+
* write against an allocation we cannot measure.
|
|
340
|
+
*/
|
|
341
|
+
siblingPrefixes?: () => Promise<string[] | null>;
|
|
335
342
|
}
|
|
336
343
|
interface ScopedR2Auth {
|
|
337
344
|
userId: string | null;
|
|
@@ -1459,14 +1466,12 @@ declare function runMigrations(db: D1Database, migrations: readonly string[]): P
|
|
|
1459
1466
|
* Wire protocol constants.
|
|
1460
1467
|
*
|
|
1461
1468
|
* The JSON WebSocket protocol uses dotted string identifiers (e.g.
|
|
1462
|
-
* `"
|
|
1469
|
+
* `"records.query"`) as the `type` discriminator. All message types are
|
|
1463
1470
|
* grouped under a single `MSG` object so imports stay tidy:
|
|
1464
1471
|
*
|
|
1465
1472
|
* import { MSG, dispatch, clientBuild } from 'deepspace'
|
|
1466
1473
|
*
|
|
1467
1474
|
* dispatch<ServerMessage>(raw, {
|
|
1468
|
-
* [MSG.GAME_STATE]: (p) => { ... },
|
|
1469
|
-
* [MSG.GAME_TICK]: (p) => { ... },
|
|
1470
1475
|
* })
|
|
1471
1476
|
*
|
|
1472
1477
|
* Each key's value is the on-wire string — grep-friendly, self-
|
|
@@ -1495,14 +1500,6 @@ declare const MSG: {
|
|
|
1495
1500
|
readonly ACK: "records.ack";
|
|
1496
1501
|
readonly LIST_SCHEMAS: "records.list_schemas";
|
|
1497
1502
|
readonly RESUBSCRIBE: "records.resubscribe";
|
|
1498
|
-
readonly GAME_STATE: "game.state";
|
|
1499
|
-
readonly GAME_INPUT: "game.input";
|
|
1500
|
-
readonly GAME_PLAYER_JOIN: "game.player_join";
|
|
1501
|
-
readonly GAME_PLAYER_LEAVE: "game.player_leave";
|
|
1502
|
-
readonly GAME_PLAYER_READY: "game.player_ready";
|
|
1503
|
-
readonly GAME_START: "game.start";
|
|
1504
|
-
readonly GAME_END: "game.end";
|
|
1505
|
-
readonly GAME_TICK: "game.tick";
|
|
1506
1503
|
readonly CANVAS_SHAPES: "canvas.shapes";
|
|
1507
1504
|
readonly CANVAS_ADD: "canvas.add";
|
|
1508
1505
|
readonly CANVAS_MOVE: "canvas.move";
|
|
@@ -1575,7 +1572,7 @@ declare const MSG: {
|
|
|
1575
1572
|
* ---------------
|
|
1576
1573
|
*
|
|
1577
1574
|
* Some message types carry different payloads depending on who's sending.
|
|
1578
|
-
* `MSG.
|
|
1575
|
+
* `MSG.RECORDS_RESUBSCRIBE`, for example, is `{}` when the client asks to
|
|
1579
1576
|
* but `{ state, tick }` when the server broadcasts the start event.
|
|
1580
1577
|
* `MSG.CANVAS_ADD` is a flat shape dict on the way in and a `{ shape }`
|
|
1581
1578
|
* wrapper on the way out. Modelling these with one union would force
|
|
@@ -1653,26 +1650,6 @@ type ServerMessage = BaseMessage<typeof MSG.QUERY_RESULT, {
|
|
|
1653
1650
|
recordId: string;
|
|
1654
1651
|
fieldName: string;
|
|
1655
1652
|
canWrite: boolean;
|
|
1656
|
-
}> | BaseMessage<typeof MSG.GAME_STATE, {
|
|
1657
|
-
state: unknown;
|
|
1658
|
-
tick: number;
|
|
1659
|
-
players: unknown[];
|
|
1660
|
-
running: boolean;
|
|
1661
|
-
}> | BaseMessage<typeof MSG.GAME_TICK, {
|
|
1662
|
-
state: unknown;
|
|
1663
|
-
tick: number;
|
|
1664
|
-
}> | BaseMessage<typeof MSG.GAME_START, {
|
|
1665
|
-
state: unknown;
|
|
1666
|
-
tick: number;
|
|
1667
|
-
}> | BaseMessage<typeof MSG.GAME_END, {
|
|
1668
|
-
state: unknown;
|
|
1669
|
-
tick: number;
|
|
1670
|
-
}> | BaseMessage<typeof MSG.GAME_PLAYER_JOIN, {
|
|
1671
|
-
player: unknown;
|
|
1672
|
-
}> | BaseMessage<typeof MSG.GAME_PLAYER_LEAVE, {
|
|
1673
|
-
userId: string;
|
|
1674
|
-
}> | BaseMessage<typeof MSG.GAME_PLAYER_READY, {
|
|
1675
|
-
userId: string;
|
|
1676
1653
|
}> | BaseMessage<typeof MSG.CANVAS_SHAPES, {
|
|
1677
1654
|
shapes: unknown[];
|
|
1678
1655
|
viewports: unknown[];
|
|
@@ -2080,8 +2057,6 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
2080
2057
|
private _fetchTiming;
|
|
2081
2058
|
private ensureInitialized;
|
|
2082
2059
|
private initializeDatabase;
|
|
2083
|
-
private migrateUsersTableIfExists;
|
|
2084
|
-
private migrateRecordsTable;
|
|
2085
2060
|
private ensureCollectionTable;
|
|
2086
2061
|
private ensureAllCollectionTables;
|
|
2087
2062
|
protected onConnect(ws: WebSocket, user: UserAttachment): Promise<ConnectionAttachment>;
|
|
@@ -2149,106 +2124,6 @@ declare class YjsRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
2149
2124
|
private broadcastRaw;
|
|
2150
2125
|
}
|
|
2151
2126
|
|
|
2152
|
-
/**
|
|
2153
|
-
* GameRoom — Authoritative game loop Durable Object.
|
|
2154
|
-
*
|
|
2155
|
-
* Extends BaseRoom with:
|
|
2156
|
-
* - Alarm-based tick loop with configurable interval
|
|
2157
|
-
* - Player management (join, leave, ready state)
|
|
2158
|
-
* - Input collection per tick, authoritative state computation
|
|
2159
|
-
* - State broadcast to all connected players
|
|
2160
|
-
*
|
|
2161
|
-
* Subclasses implement game logic via lifecycle hooks:
|
|
2162
|
-
* onTick, onPlayerJoin, onPlayerLeave, onGameStart, onGameEnd
|
|
2163
|
-
*
|
|
2164
|
-
* Message types: game.*
|
|
2165
|
-
*/
|
|
2166
|
-
|
|
2167
|
-
interface GameRoomConfig {
|
|
2168
|
-
/** Ticks per second (default: 20) */
|
|
2169
|
-
tickRate?: number;
|
|
2170
|
-
/** Minimum players to start (default: 1) */
|
|
2171
|
-
minPlayers?: number;
|
|
2172
|
-
/** Maximum players (default: unlimited) */
|
|
2173
|
-
maxPlayers?: number;
|
|
2174
|
-
}
|
|
2175
|
-
interface Player {
|
|
2176
|
-
userId: string;
|
|
2177
|
-
userName: string;
|
|
2178
|
-
ready: boolean;
|
|
2179
|
-
connectedAt: string;
|
|
2180
|
-
data: Record<string, unknown>;
|
|
2181
|
-
}
|
|
2182
|
-
interface GameInput {
|
|
2183
|
-
userId: string;
|
|
2184
|
-
action: string;
|
|
2185
|
-
data: Record<string, unknown>;
|
|
2186
|
-
tick: number;
|
|
2187
|
-
}
|
|
2188
|
-
interface GameAttachment extends UserAttachment {
|
|
2189
|
-
joinedAt: string;
|
|
2190
|
-
/** True for member/admin roles; false for viewers, unauthenticated anon, spectators. */
|
|
2191
|
-
canWrite: boolean;
|
|
2192
|
-
}
|
|
2193
|
-
declare abstract class GameRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
2194
|
-
private config;
|
|
2195
|
-
private players;
|
|
2196
|
-
private inputBuffer;
|
|
2197
|
-
private currentTick;
|
|
2198
|
-
private gameState;
|
|
2199
|
-
private running;
|
|
2200
|
-
private initialized;
|
|
2201
|
-
constructor(state: DurableObjectState, env: unknown, config?: GameRoomConfig);
|
|
2202
|
-
private ensureInitialized;
|
|
2203
|
-
private persistState;
|
|
2204
|
-
protected onConnect(ws: WebSocket, user: UserAttachment): GameAttachment;
|
|
2205
|
-
protected onMessage(ws: WebSocket, user: UserAttachment, message: {
|
|
2206
|
-
type: string;
|
|
2207
|
-
[key: string]: unknown;
|
|
2208
|
-
}): Promise<void>;
|
|
2209
|
-
protected onDisconnect(_ws: WebSocket, user: UserAttachment): void;
|
|
2210
|
-
protected onAlarm(): Promise<void>;
|
|
2211
|
-
private checkAutoStart;
|
|
2212
|
-
private startGame;
|
|
2213
|
-
private stopGame;
|
|
2214
|
-
protected getGameState(): Record<string, unknown>;
|
|
2215
|
-
protected setGameState(state: Record<string, unknown>): void;
|
|
2216
|
-
protected getPlayers(): Player[];
|
|
2217
|
-
protected isRunning(): boolean;
|
|
2218
|
-
protected getCurrentTick(): number;
|
|
2219
|
-
/**
|
|
2220
|
-
* Called each tick with current state and collected inputs.
|
|
2221
|
-
* Return the new game state, or undefined to keep current state.
|
|
2222
|
-
*/
|
|
2223
|
-
protected abstract onTick(state: Record<string, unknown>, inputs: GameInput[], tick: number): Record<string, unknown> | undefined | Promise<Record<string, unknown> | undefined>;
|
|
2224
|
-
/** Called when a player connects */
|
|
2225
|
-
protected onPlayerJoin(_player: Player): void;
|
|
2226
|
-
/** Called when a player disconnects */
|
|
2227
|
-
protected onPlayerLeave(_player: Player): void;
|
|
2228
|
-
/** Called when the game starts */
|
|
2229
|
-
protected onGameStart(): void;
|
|
2230
|
-
/** Called when the game ends */
|
|
2231
|
-
protected onGameEnd(_finalState: Record<string, unknown>): void;
|
|
2232
|
-
/**
|
|
2233
|
-
* Called once when the DO first hydrates persisted state from storage.
|
|
2234
|
-
* Receives the parsed state blob as it was written by a previous build.
|
|
2235
|
-
* Return the state object to install as `gameState`.
|
|
2236
|
-
*
|
|
2237
|
-
* Subclasses with evolving schemas should override this hook to:
|
|
2238
|
-
* - merge new fields onto a default template,
|
|
2239
|
-
* - upgrade shapes across versioned states,
|
|
2240
|
-
* - or discard stale blobs entirely by returning a fresh object.
|
|
2241
|
-
*
|
|
2242
|
-
* The default implementation is a pass-through, preserving the legacy
|
|
2243
|
-
* "stored blob is gospel" behavior for subclasses that don't care.
|
|
2244
|
-
*
|
|
2245
|
-
* If JSON parsing of the stored blob fails this hook is NOT called — the
|
|
2246
|
-
* DO starts with an empty state and the subclass's `onGameStart` (or
|
|
2247
|
-
* first `onTick`) is responsible for initializing.
|
|
2248
|
-
*/
|
|
2249
|
-
protected onHydrateState(stored: Record<string, unknown>): Record<string, unknown>;
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
2127
|
/**
|
|
2253
2128
|
* CanvasRoom — Spatial canvas Durable Object (tldraw-style).
|
|
2254
2129
|
*
|
|
@@ -2612,11 +2487,10 @@ type DOManifest = DOManifestEntry[];
|
|
|
2612
2487
|
* @example
|
|
2613
2488
|
* const manifest = [
|
|
2614
2489
|
* { binding: 'RECORD_ROOMS', className: 'AppRecordRoom', sqlite: true },
|
|
2615
|
-
* { binding: 'GAME_ROOMS', className: 'AppGameRoom', sqlite: true },
|
|
2616
2490
|
* ] as const satisfies DOManifest
|
|
2617
2491
|
*
|
|
2618
2492
|
* type Env = BaseEnv & DOBindings<typeof manifest>
|
|
2619
|
-
* // => { RECORD_ROOMS: DurableObjectNamespace
|
|
2493
|
+
* // => { RECORD_ROOMS: DurableObjectNamespace }
|
|
2620
2494
|
*/
|
|
2621
2495
|
type DOBindings<T extends readonly DOManifestEntry[]> = {
|
|
2622
2496
|
[K in T[number]['binding']]: DurableObjectNamespace;
|
|
@@ -4659,4 +4533,4 @@ declare class RefundError extends Error {
|
|
|
4659
4533
|
constructor(message: string, status: number);
|
|
4660
4534
|
}
|
|
4661
4535
|
|
|
4662
|
-
export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_ID_RE, APP_NAME_RULES,
|
|
4536
|
+
export { ACCOUNT_STORAGE_LIMIT_BYTES, AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_ID_RE, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CancelSubscriptionError, type CancelSubscriptionOpts, type CancelSubscriptionResult, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, 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 DebugApiContext, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAgentDiagnosticContext, DeepSpaceAgentModelError, DeepSpaceAgentProfileError, type DeepSpaceAgentStream, type DeepSpaceAgentStreamOptions, 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 GetActionData, type GlobalDOType, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, MAX_APP_FILE_BYTES, MAX_DEPLOY_ASSET_FILE_BYTES, MAX_UPLOAD_PARTS, MAX_UPLOAD_REQUEST_BYTES, MESSAGES_SCHEMA, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlanInfo, type PlatformWorkerEnv, type PrefixResult, type PresencePeer, PresenceRoom, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, REGISTRY_INSTANCE, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, RESOURCE_ID_RE, type RecordContext, RecordRoom, type RecordRoomConfig, RefundError, type RefundOpts, type RefundResult, RegistryClientError, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, STRICT_APP_ID_RE, SYSTEM_COLLECTION_SCHEMAS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type SharedConnection, type StorageAdmission, type StoredRecord, SubscriptionAuthError, type SubscriptionContext, type SubscriptionRead, SubscriptionRequiredError, type SubscriptionStatus, type Summarizer, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, type ToolsApiContext, UPLOAD_PART_BYTES, USERS_COLUMNS, type User, type UserAttachment, type UserContext, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, type YjsContext, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, broadcastChange, broadcastYjsUpdate, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, cancelSubscription, capToolResultSize, captureScreenshot, checkFieldPermissions, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDeepSpaceAI, createDeepSpaceAuth, createScopedR2Handler, dataToColumnValues, decodeJwtPayload, deepSpaceAgentErrorSummary, deleteChatCascade, deleteRecord, enqueueJob, executeQuery, formatBytes, getAllUsers, getChat, getGlobalDOSchemas, getGlobalDOType, getOrCreateYjsDoc, getRecord, getRolePermissions, getSubscription, getUser, getYjsDocKey, handleApiRequest, handleDelete, handlePut, handleSetRole, handleSubscribe, handleToolsRequest, handleUnsubscribe, handleUserList, handleUserUpdate, handleYjsBinaryMessage, handleYjsJoin, handleYjsLeave, isAutoProvision, isFilesVerbPath, isOwner, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, lintSchema, loadMessages, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, noopPermissionContext, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, putRecord, readRecord, recordMatchesSubscription, refundInvoice, registerUser, registryErrorJson, registryStub, requireSubscription, resolveAppName, resolveColumn, rowToData, runMigrations, saveYjsDoc, storageLimitForTier, storageQuotaMessage, streamDeepSpaceAgent, timingSafeEqualHex, timingSafeEqualStrings, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema };
|