deepspace 0.4.5 → 0.5.1
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/README.md +90 -0
- package/dist/cli.js +3590 -1485
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +876 -3664
- package/dist/index.js +511 -366
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +132 -61
- package/dist/server.js +149 -110
- package/dist/server.js.map +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/worker.d.ts +128 -59
- package/dist/worker.js +144 -99
- package/dist/worker.js.map +1 -1
- package/features/admin-page/src/AdminPage.tsx +3 -5
- package/features/canvas/src/CanvasEditorPage.tsx +0 -2
- package/features/canvas/src/components/CanvasView.tsx +1 -1
- package/features/docs/src/LibrarySidebar.tsx +7 -1
- package/features/docs/src/editor/useDocEditor.ts +5 -1
- package/features/docs/src/use-yjs-room-with-awareness.ts +4 -0
- package/features/file-attachments/src/AttachmentsPage.tsx +7 -1
- package/features/file-attachments/src/useFilePreview.ts +7 -5
- package/features/file-manager/src/FileManagerPage.tsx +2 -3
- package/features/integration-test/feature.json +10 -3
- package/features/integration-test/src/IntegrationTestPage.tsx +15 -12
- package/features/landing/src/LandingPage.tsx +1 -1
- package/features/landing/src/sections/FeaturesGridSection.tsx +0 -92
- package/features/messaging/src/ChatPage.tsx +6 -1
- package/features/messaging/src/components/chat/MessageItem.tsx +5 -1
- package/features/messaging/src/hooks/useChatChannel.ts +23 -7
- package/features/presence-test/feature.json +2 -1
- package/features/sidebar/src/AppSidebar.tsx +1 -1
- package/features/tasks/src/TasksPage.tsx +1 -1
- package/features/testing/feature.json +2 -1
- package/features/testing/src/TestPage.tsx +8 -8
- package/package.json +8 -4
- package/scripts/add-feature.cjs +296 -282
- package/dist/testing.d.ts +0 -115
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/testing/fixtures.ts","../src/testing/accounts.ts","../src/testing/storage-state.ts"],"sourcesContent":["/**\n * Multi-user Playwright fixture for DeepSpace apps.\n *\n * Usage:\n *\n * import { test, expect } from 'deepspace/testing'\n *\n * test('A sends, B sees', async ({ users }) => {\n * const [a, b] = await users(2)\n * await a.page.goto('/chat')\n * await b.page.goto('/chat')\n * await a.page.getByTestId('message-input').fill('hi')\n * await a.page.getByTestId('send-message-btn').click()\n * await expect(b.page.getByText('hi')).toBeVisible()\n * })\n *\n * `users(N)` picks the first N test accounts from\n * `~/.deepspace/test-accounts.json` (created via\n * `deepspace test-accounts create`). `users(['Alice', 'Bob'])` picks\n * specific accounts by name.\n *\n * Each user gets a separate browser context with cached storageState\n * (per-account JSON in `~/.deepspace/playwright-states/`). Sign-in\n * happens once per account, not once per test, sidestepping Better\n * Auth's per-IP rate limit on `/api/auth/sign-in/email`.\n *\n * Contexts are auto-closed when the test finishes.\n */\n\nimport { test as baseTest, type Browser, type BrowserContext, type Page } from '@playwright/test'\nimport {\n type TestAccount,\n pickTestAccounts,\n findTestAccountByName,\n} from './accounts'\nimport { ensureStorageState } from './storage-state'\n\nexport interface MultiplayerUser {\n context: BrowserContext\n page: Page\n email: string\n name: string\n /** Test account user ID, if known from the accounts registry. */\n userId?: string\n}\n\n/**\n * Fixture function signature. Pass either a count (`users(2)`) or an\n * array of account names (`users(['Alice', 'Bob'])`). Returns one entry\n * per requested user.\n */\nexport type UsersFixture = (\n selector: number | string[],\n options?: { label?: string },\n) => Promise<MultiplayerUser[]>\n\ninterface MultiplayerFixtures {\n users: UsersFixture\n}\n\nasync function buildUser(\n browser: Browser,\n account: TestAccount,\n baseURL: string,\n): Promise<{ user: MultiplayerUser; cleanup: () => Promise<void> }> {\n const statePath = await ensureStorageState(browser, account, baseURL)\n const context = await browser.newContext({ storageState: statePath, baseURL })\n const page = await context.newPage()\n return {\n user: {\n context,\n page,\n email: account.email,\n name: account.name ?? account.email.split('@')[0],\n userId: account.userId,\n },\n cleanup: async () => {\n await context.close()\n },\n }\n}\n\nexport const test = baseTest.extend<MultiplayerFixtures>({\n users: async ({ browser, baseURL }, use) => {\n if (!baseURL) {\n throw new Error(\n '`users` fixture requires a baseURL. Set it on your Playwright config ' +\n '(e.g. `use: { baseURL: \"http://localhost:5173\" }`) or via the ' +\n 'webServer.url shortcut.',\n )\n }\n\n const cleanups: Array<() => Promise<void>> = []\n\n const usersFn: UsersFixture = async (selector, options) => {\n const accounts: TestAccount[] = Array.isArray(selector)\n ? selector.map((name) => findTestAccountByName(name))\n : pickTestAccounts(selector, options)\n\n const built = await Promise.all(\n accounts.map((acct) => buildUser(browser, acct, baseURL)),\n )\n for (const b of built) cleanups.push(b.cleanup)\n return built.map((b) => b.user)\n }\n\n await use(usersFn)\n\n // Tear down any contexts we created. Errors are swallowed — a test\n // failure shouldn't be masked by a cleanup error.\n for (const cleanup of cleanups) {\n await cleanup().catch(() => {})\n }\n },\n})\n\nexport { expect } from '@playwright/test'\n","/**\n * Account-credential plumbing for the testing module.\n *\n * Reads test accounts from `~/.deepspace/test-accounts.json` (the same\n * file `deepspace test-accounts create` writes). Each account has at\n * minimum `{email, password}`; `name` and `label` are optional.\n *\n * Used by the multi-user Playwright fixture in `./fixtures.ts` and is\n * also exported standalone in case suites want to do their own\n * orchestration.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface TestAccount {\n email: string\n password: string\n name?: string\n label?: string | null\n id?: string\n userId?: string\n createdAt?: number\n}\n\nconst ACCOUNTS_PATH = join(homedir(), '.deepspace', 'test-accounts.json')\n\n/**\n * Load all test accounts the developer has created. Returns an empty\n * array if the file doesn't exist yet.\n */\nexport function loadAllTestAccounts(): TestAccount[] {\n if (!existsSync(ACCOUNTS_PATH)) return []\n try {\n const raw = JSON.parse(readFileSync(ACCOUNTS_PATH, 'utf-8'))\n if (!Array.isArray(raw)) return []\n // Filter out any malformed entries (missing email or password). Keep\n // bare {email, password} rows so the file format stays forgiving.\n return raw.filter(\n (r) => r && typeof r.email === 'string' && typeof r.password === 'string',\n )\n } catch {\n return []\n }\n}\n\n/**\n * Pick `count` test accounts from the local registry, optionally\n * filtered by `label`. Order-stable: sorted by `createdAt` ascending so\n * the first test account you created is always the first one returned.\n *\n * Throws with a helpful message if not enough accounts exist.\n */\nexport function pickTestAccounts(\n count: number,\n options?: { label?: string },\n): TestAccount[] {\n const all = loadAllTestAccounts()\n const filtered = options?.label\n ? all.filter((a) => a.label === options.label)\n : all\n const sorted = filtered.slice().sort((a, b) => (a.createdAt ?? 0) - (b.createdAt ?? 0))\n\n if (sorted.length < count) {\n const labelHint = options?.label ? ` (label=\"${options.label}\")` : ''\n throw new Error(\n `Multiplayer test needs ${count} test accounts${labelHint}, but only ${sorted.length} ` +\n `are present in ${ACCOUNTS_PATH}. Create more with:\\n` +\n ` deepspace test-accounts create --email <name>@deepspace.test --password <pw> --name \"<name>\"${\n options?.label ? ` --label ${options.label}` : ''\n }`,\n )\n }\n\n return sorted.slice(0, count)\n}\n\n/**\n * Find a single account by name. Used by `users(['Alice', 'Bob'])`.\n * Throws if not found.\n */\nexport function findTestAccountByName(name: string): TestAccount {\n const all = loadAllTestAccounts()\n const match = all.find((a) => a.name === name)\n if (!match) {\n throw new Error(\n `No test account named \"${name}\" in ${ACCOUNTS_PATH}. Create with:\\n` +\n ` deepspace test-accounts create --email ${name.toLowerCase()}@deepspace.test --password <pw> --name \"${name}\"`,\n )\n }\n return match\n}\n","/**\n * Per-account `storageState` cache for Playwright.\n *\n * Better Auth applies a per-IP rate limit on `/api/auth/sign-in/email`\n * (~5 sign-ins / 60s / endpoint). A multiplayer suite that spins up\n * 5+ users per spec would hit the limit and start failing in non-obvious\n * ways. This module signs each account in *once*, persists the\n * resulting browser cookies + storage to disk, and reuses the file on\n * subsequent runs.\n *\n * Cache layout:\n * ~/.deepspace/playwright-states/<sha256(email)>.json\n *\n * Validity: a cached file is reused if Playwright successfully loads it\n * AND the resulting context produces a non-anonymous session on the\n * target app. If validation fails, we fall back to a fresh sign-in and\n * overwrite the cache.\n */\n\nimport { createHash } from 'node:crypto'\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, statSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type { Browser, BrowserContext } from '@playwright/test'\n\nconst STATES_DIR = join(homedir(), '.deepspace', 'playwright-states')\n\n/** Default freshness window — re-sign-in if the cache is older than this. */\nconst DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000 // 7 days\n\nfunction statePathForEmail(email: string): string {\n const hash = createHash('sha256').update(email.trim().toLowerCase()).digest('hex').slice(0, 24)\n return join(STATES_DIR, `${hash}.json`)\n}\n\nfunction ensureStatesDir() {\n if (!existsSync(STATES_DIR)) mkdirSync(STATES_DIR, { recursive: true })\n}\n\n/** Returns true if a cache file exists and is younger than `maxAgeMs`. */\nfunction isCacheFresh(path: string, maxAgeMs: number): boolean {\n if (!existsSync(path)) return false\n try {\n const age = Date.now() - statSync(path).mtimeMs\n return age < maxAgeMs\n } catch {\n return false\n }\n}\n\n/**\n * Sign `account` in by POSTing `/api/auth/sign-in/email` against\n * `baseURL` and capturing the resulting cookies. Returns the path to the\n * Playwright `storageState` JSON file.\n *\n * The browser-driven approach is intentional: we want the cookies set\n * on the same origin Playwright contexts will load from, otherwise the\n * Set-Cookie domain attribute won't match.\n */\nasync function signInAndSaveState(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n outPath: string,\n): Promise<string> {\n ensureStatesDir()\n const ctx = await browser.newContext({ baseURL })\n try {\n const page = await ctx.newPage()\n // Hit the app first so the origin is established (some auth plugins\n // require a same-origin Origin header on sign-in).\n await page.goto('/')\n const ok = await page.evaluate(\n async ({ email, password }: { email: string; password: string }) => {\n const res = await fetch('/api/auth/sign-in/email', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n })\n return res.ok\n },\n account,\n )\n if (!ok) {\n throw new Error(\n `Sign-in failed for ${account.email}. Check the password is current; ` +\n `if the account was deleted on the server, re-create with ` +\n `\\`deepspace test-accounts create\\`.`,\n )\n }\n await ctx.storageState({ path: outPath })\n return outPath\n } finally {\n await ctx.close()\n }\n}\n\nexport interface EnsureStorageStateOptions {\n /** Max age of a cached state file before we re-sign-in. Default 7 days. */\n maxAgeMs?: number\n /** Force a fresh sign-in even if the cache is fresh. */\n force?: boolean\n}\n\n/**\n * Ensure a Playwright `storageState` file exists for `account` and\n * return its path. Signs in once if the cache is missing, stale, or\n * `force: true`.\n */\nexport async function ensureStorageState(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n options: EnsureStorageStateOptions = {},\n): Promise<string> {\n const path = statePathForEmail(account.email)\n const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS\n\n if (!options.force && isCacheFresh(path, maxAgeMs)) {\n return path\n }\n\n return signInAndSaveState(browser, account, baseURL, path)\n}\n\n/**\n * Convenience: open a fresh `BrowserContext` for `account` using the\n * cached storage state (signing in if needed). The caller is responsible\n * for closing the context.\n */\nexport async function newSignedInContext(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n options: EnsureStorageStateOptions = {},\n): Promise<BrowserContext> {\n const statePath = await ensureStorageState(browser, account, baseURL, options)\n return browser.newContext({ storageState: statePath, baseURL })\n}\n\n/** Read a cached storageState file (mostly for debugging). */\nexport function readCachedState(email: string): unknown | null {\n const path = statePathForEmail(email)\n if (!existsSync(path)) return null\n try {\n return JSON.parse(readFileSync(path, 'utf-8'))\n } catch {\n return null\n }\n}\n\n/** Where the cache for `email` lives. Useful for diagnostics. */\nexport function getStatePathForEmail(email: string): string {\n return statePathForEmail(email)\n}\n"],"mappings":"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","names":["existsSync","readFileSync","homedir","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/testing/fixtures.ts","../src/testing/accounts.ts","../src/testing/storage-state.ts"],"sourcesContent":["/**\n * Multi-user Playwright fixture for DeepSpace apps.\n *\n * Usage:\n *\n * import { test, expect } from 'deepspace/testing'\n *\n * test('A sends, B sees', async ({ users }) => {\n * const [a, b] = await users(2)\n * await a.page.goto('/chat')\n * await b.page.goto('/chat')\n * await a.page.getByTestId('message-input').fill('hi')\n * await a.page.getByTestId('send-message-btn').click()\n * await expect(b.page.getByText('hi')).toBeVisible()\n * })\n *\n * `users(N)` picks the first N test accounts from\n * `~/.deepspace/test-accounts.json` (created via\n * `deepspace test-accounts create`). `users(['Alice', 'Bob'])` picks\n * specific accounts by name.\n *\n * Each user gets a separate browser context with cached storageState\n * (per-account JSON in `~/.deepspace/playwright-states/`). Sign-in\n * happens once per account, not once per test, sidestepping Better\n * Auth's per-IP rate limit on `/api/auth/sign-in/email`.\n *\n * Contexts are auto-closed when the test finishes.\n */\n\nimport { test as baseTest, type Browser, type BrowserContext, type Page } from '@playwright/test'\nimport {\n type TestAccount,\n pickTestAccounts,\n findTestAccountByName,\n} from './accounts'\nimport { ensureStorageState } from './storage-state'\n\nexport interface MultiplayerUser {\n context: BrowserContext\n page: Page\n email: string\n name: string\n /** Test account user ID, if known from the accounts registry. */\n userId?: string\n}\n\n/**\n * Fixture function signature. Pass either a count (`users(2)`) or an\n * array of account names (`users(['Alice', 'Bob'])`). Returns one entry\n * per requested user.\n */\nexport type UsersFixture = (\n selector: number | string[],\n options?: { label?: string },\n) => Promise<MultiplayerUser[]>\n\ninterface MultiplayerFixtures {\n users: UsersFixture\n}\n\nasync function buildUser(\n browser: Browser,\n account: TestAccount,\n baseURL: string,\n): Promise<{ user: MultiplayerUser; cleanup: () => Promise<void> }> {\n const statePath = await ensureStorageState(browser, account, baseURL)\n const context = await browser.newContext({ storageState: statePath, baseURL })\n const page = await context.newPage()\n return {\n user: {\n context,\n page,\n email: account.email,\n name: account.name ?? account.email.split('@')[0],\n userId: account.userId,\n },\n cleanup: async () => {\n await context.close()\n },\n }\n}\n\nexport const test = baseTest.extend<MultiplayerFixtures>({\n users: async ({ browser, baseURL }, use) => {\n if (!baseURL) {\n throw new Error(\n '`users` fixture requires a baseURL. Set it on your Playwright config ' +\n '(e.g. `use: { baseURL: \"http://localhost:5173\" }`) or via the ' +\n 'webServer.url shortcut.',\n )\n }\n\n const cleanups: Array<() => Promise<void>> = []\n\n const usersFn: UsersFixture = async (selector, options) => {\n const accounts: TestAccount[] = Array.isArray(selector)\n ? selector.map((name) => findTestAccountByName(name))\n : pickTestAccounts(selector, options)\n\n const built = await Promise.all(\n accounts.map((acct) => buildUser(browser, acct, baseURL)),\n )\n for (const b of built) cleanups.push(b.cleanup)\n return built.map((b) => b.user)\n }\n\n await use(usersFn)\n\n // Tear down any contexts we created. Errors are swallowed — a test\n // failure shouldn't be masked by a cleanup error.\n for (const cleanup of cleanups) {\n await cleanup().catch(() => {})\n }\n },\n})\n\nexport { expect } from '@playwright/test'\n","/**\n * Account-credential plumbing for the testing module.\n *\n * Reads test accounts from `~/.deepspace/test-accounts.json` (the same\n * file `deepspace test-accounts create` writes). Each account has at\n * minimum `{email, password}`; `name` and `label` are optional.\n *\n * Used by the multi-user Playwright fixture in `./fixtures.ts` and is\n * also exported standalone in case suites want to do their own\n * orchestration.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface TestAccount {\n email: string\n password: string\n name?: string\n label?: string | null\n id?: string\n userId?: string\n createdAt?: number\n}\n\nconst ACCOUNTS_PATH = join(homedir(), '.deepspace', 'test-accounts.json')\n\n/**\n * Load all test accounts the developer has created. Returns an empty\n * array if the file doesn't exist yet.\n */\nexport function loadAllTestAccounts(): TestAccount[] {\n if (!existsSync(ACCOUNTS_PATH)) return []\n try {\n const raw = JSON.parse(readFileSync(ACCOUNTS_PATH, 'utf-8'))\n if (!Array.isArray(raw)) return []\n // Filter out any malformed entries (missing email or password). Keep\n // bare {email, password} rows so the file format stays forgiving.\n return raw.filter(\n (r) => r && typeof r.email === 'string' && typeof r.password === 'string',\n )\n } catch {\n return []\n }\n}\n\n/**\n * Pick `count` test accounts from the local registry, optionally\n * filtered by `label`. Order-stable: sorted by `createdAt` ascending so\n * the first test account you created is always the first one returned.\n *\n * Throws with a helpful message if not enough accounts exist.\n */\nexport function pickTestAccounts(\n count: number,\n options?: { label?: string },\n): TestAccount[] {\n const all = loadAllTestAccounts()\n const filtered = options?.label\n ? all.filter((a) => a.label === options.label)\n : all\n const sorted = filtered.slice().sort((a, b) => (a.createdAt ?? 0) - (b.createdAt ?? 0))\n\n if (sorted.length < count) {\n const labelHint = options?.label ? ` (label=\"${options.label}\")` : ''\n throw new Error(\n `Multiplayer test needs ${count} test accounts${labelHint}, but only ${sorted.length} ` +\n `are present in ${ACCOUNTS_PATH}. Create more with:\\n` +\n ` deepspace test-accounts create --email <name>@deepspace.test --password <pw> --name \"<name>\"${\n options?.label ? ` --label ${options.label}` : ''\n }`,\n )\n }\n\n return sorted.slice(0, count)\n}\n\n/**\n * Find a single account by name. Used by `users(['Alice', 'Bob'])`.\n * Throws if not found.\n */\nexport function findTestAccountByName(name: string): TestAccount {\n const all = loadAllTestAccounts()\n const match = all.find((a) => a.name === name)\n if (!match) {\n throw new Error(\n `No test account named \"${name}\" in ${ACCOUNTS_PATH}. Create with:\\n` +\n ` deepspace test-accounts create --email ${name.toLowerCase()}@deepspace.test --password <pw> --name \"${name}\"`,\n )\n }\n return match\n}\n","/**\n * Per-account `storageState` cache for Playwright.\n *\n * Better Auth applies a per-IP rate limit on `/api/auth/sign-in/email`\n * (~5 sign-ins / 60s / endpoint). A multiplayer suite that spins up\n * 5+ users per spec would hit the limit and start failing in non-obvious\n * ways. This module signs each account in *once*, persists the\n * resulting browser cookies + storage to disk, and reuses the file on\n * subsequent runs.\n *\n * Cache layout:\n * ~/.deepspace/playwright-states/<sha256(email)>.json\n *\n * Validity: a cached file is reused if Playwright successfully loads it\n * AND the resulting context produces a non-anonymous session on the\n * target app. If validation fails, we fall back to a fresh sign-in and\n * overwrite the cache.\n */\n\nimport { createHash } from 'node:crypto'\nimport { existsSync, mkdirSync, readFileSync, statSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type { Browser, BrowserContext } from '@playwright/test'\n\nconst STATES_DIR = join(homedir(), '.deepspace', 'playwright-states')\n\n/** Default freshness window — re-sign-in if the cache is older than this. */\nconst DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000 // 7 days\n\nfunction statePathForEmail(email: string): string {\n const hash = createHash('sha256').update(email.trim().toLowerCase()).digest('hex').slice(0, 24)\n return join(STATES_DIR, `${hash}.json`)\n}\n\nfunction ensureStatesDir() {\n if (!existsSync(STATES_DIR)) mkdirSync(STATES_DIR, { recursive: true })\n}\n\n/** Returns true if a cache file exists and is younger than `maxAgeMs`. */\nfunction isCacheFresh(path: string, maxAgeMs: number): boolean {\n if (!existsSync(path)) return false\n try {\n const age = Date.now() - statSync(path).mtimeMs\n return age < maxAgeMs\n } catch {\n return false\n }\n}\n\n/**\n * Sign `account` in by POSTing `/api/auth/sign-in/email` against\n * `baseURL` and capturing the resulting cookies. Returns the path to the\n * Playwright `storageState` JSON file.\n *\n * The browser-driven approach is intentional: we want the cookies set\n * on the same origin Playwright contexts will load from, otherwise the\n * Set-Cookie domain attribute won't match.\n */\nasync function signInAndSaveState(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n outPath: string,\n): Promise<string> {\n ensureStatesDir()\n const ctx = await browser.newContext({ baseURL })\n try {\n const page = await ctx.newPage()\n // Hit the app first so the origin is established (some auth plugins\n // require a same-origin Origin header on sign-in).\n await page.goto('/')\n const ok = await page.evaluate(\n async ({ email, password }: { email: string; password: string }) => {\n const res = await fetch('/api/auth/sign-in/email', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n })\n return res.ok\n },\n account,\n )\n if (!ok) {\n throw new Error(\n `Sign-in failed for ${account.email}. Check the password is current; ` +\n `if the account was deleted on the server, re-create with ` +\n `\\`deepspace test-accounts create\\`.`,\n )\n }\n await ctx.storageState({ path: outPath })\n return outPath\n } finally {\n await ctx.close()\n }\n}\n\nexport interface EnsureStorageStateOptions {\n /** Max age of a cached state file before we re-sign-in. Default 7 days. */\n maxAgeMs?: number\n /** Force a fresh sign-in even if the cache is fresh. */\n force?: boolean\n}\n\n/**\n * Ensure a Playwright `storageState` file exists for `account` and\n * return its path. Signs in once if the cache is missing, stale, or\n * `force: true`.\n */\nexport async function ensureStorageState(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n options: EnsureStorageStateOptions = {},\n): Promise<string> {\n const path = statePathForEmail(account.email)\n const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS\n\n if (!options.force && isCacheFresh(path, maxAgeMs)) {\n return path\n }\n\n return signInAndSaveState(browser, account, baseURL, path)\n}\n\n/**\n * Convenience: open a fresh `BrowserContext` for `account` using the\n * cached storage state (signing in if needed). The caller is responsible\n * for closing the context.\n */\nexport async function newSignedInContext(\n browser: Browser,\n account: { email: string; password: string },\n baseURL: string,\n options: EnsureStorageStateOptions = {},\n): Promise<BrowserContext> {\n const statePath = await ensureStorageState(browser, account, baseURL, options)\n return browser.newContext({ storageState: statePath, baseURL })\n}\n\n/** Read a cached storageState file (mostly for debugging). */\nexport function readCachedState(email: string): unknown | null {\n const path = statePathForEmail(email)\n if (!existsSync(path)) return null\n try {\n return JSON.parse(readFileSync(path, 'utf-8'))\n } catch {\n return null\n }\n}\n\n/** Where the cache for `email` lives. Useful for diagnostics. */\nexport function getStatePathForEmail(email: string): string {\n return statePathForEmail(email)\n}\n"],"mappings":"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","names":["existsSync","readFileSync","homedir","join"]}
|
package/dist/worker.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as Y from 'yjs';
|
|
2
2
|
import { LanguageModel, ToolSet, ModelMessage } from 'ai';
|
|
3
|
+
import * as zod_v4_core from 'zod/v4/core';
|
|
4
|
+
import * as zod from 'zod';
|
|
3
5
|
import * as better_auth from 'better-auth';
|
|
4
6
|
import { betterAuth } from 'better-auth';
|
|
5
7
|
import * as better_auth_plugins from 'better-auth/plugins';
|
|
@@ -917,7 +919,7 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
917
919
|
fetch(request: Request): Promise<Response>;
|
|
918
920
|
private handleWebSocketUpgrade;
|
|
919
921
|
webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
|
|
920
|
-
webSocketClose(ws: WebSocket,
|
|
922
|
+
webSocketClose(ws: WebSocket, _code: number, _reason: string): Promise<void>;
|
|
921
923
|
webSocketError(ws: WebSocket, error: unknown): Promise<void>;
|
|
922
924
|
alarm(): Promise<void>;
|
|
923
925
|
/**
|
|
@@ -925,7 +927,7 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
925
927
|
* Return an augmented attachment to serialize on the WebSocket,
|
|
926
928
|
* or void to use the default attachment.
|
|
927
929
|
*/
|
|
928
|
-
protected onConnect(
|
|
930
|
+
protected onConnect(_ws: WebSocket, _user: UserAttachment): UserAttachment | void | Promise<UserAttachment | void>;
|
|
929
931
|
/**
|
|
930
932
|
* Called for each parsed JSON message.
|
|
931
933
|
*/
|
|
@@ -940,7 +942,7 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
940
942
|
/**
|
|
941
943
|
* Called when a WebSocket disconnects.
|
|
942
944
|
*/
|
|
943
|
-
protected onDisconnect(
|
|
945
|
+
protected onDisconnect(_ws: WebSocket, _user: UserAttachment): void | Promise<void>;
|
|
944
946
|
/**
|
|
945
947
|
* Called for HTTP requests that are NOT WebSocket upgrades.
|
|
946
948
|
*/
|
|
@@ -1322,7 +1324,6 @@ declare class SchemaRegistry {
|
|
|
1322
1324
|
registerTrusted(schema: CollectionSchema): void;
|
|
1323
1325
|
get(name: string): CollectionSchema | undefined;
|
|
1324
1326
|
has(name: string): boolean;
|
|
1325
|
-
hasTrusted(name: string): boolean;
|
|
1326
1327
|
all(): CollectionSchema[];
|
|
1327
1328
|
names(): string[];
|
|
1328
1329
|
}
|
|
@@ -1394,6 +1395,12 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1394
1395
|
private ownerUserId;
|
|
1395
1396
|
/** True until the first fetch() completes — detects hibernation wake-up */
|
|
1396
1397
|
private freshConstruct;
|
|
1398
|
+
/**
|
|
1399
|
+
* Per-connection `[DO Perf]` timing logs are noisy on every hot path, so
|
|
1400
|
+
* they're gated behind a `DEEPSPACE_DO_PERF` env binding (set it to any
|
|
1401
|
+
* truthy value on the worker to opt in). Off by default.
|
|
1402
|
+
*/
|
|
1403
|
+
private get perfLogEnabled();
|
|
1397
1404
|
constructor(state: DurableObjectState, env: unknown, schemas?: CollectionSchema[], config?: RecordRoomConfig);
|
|
1398
1405
|
private getPermissionContext;
|
|
1399
1406
|
fetch(request: Request): Promise<Response>;
|
|
@@ -1406,12 +1413,13 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1406
1413
|
private ensureCollectionTable;
|
|
1407
1414
|
private ensureAllCollectionTables;
|
|
1408
1415
|
protected onConnect(ws: WebSocket, user: UserAttachment): Promise<ConnectionAttachment>;
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1416
|
+
/**
|
|
1417
|
+
* Required to satisfy BaseRoom's abstract contract, but never invoked:
|
|
1418
|
+
* RecordRoom overrides `webSocketMessage`/`webSocketClose` directly (below),
|
|
1419
|
+
* so the BaseRoom dispatch path that would call this never runs. All real
|
|
1420
|
+
* message handling lives in `handleRecordMessage`.
|
|
1421
|
+
*/
|
|
1422
|
+
protected onMessage(): void;
|
|
1415
1423
|
webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
|
|
1416
1424
|
webSocketClose(ws: WebSocket, code: number, reason: string): Promise<void>;
|
|
1417
1425
|
webSocketError(ws: WebSocket, error: unknown): Promise<void>;
|
|
@@ -1455,12 +1463,12 @@ declare class YjsRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1455
1463
|
private getDoc;
|
|
1456
1464
|
private persistDoc;
|
|
1457
1465
|
protected onConnect(ws: WebSocket, user: UserAttachment): YjsAttachment;
|
|
1458
|
-
protected onMessage(
|
|
1466
|
+
protected onMessage(_ws: WebSocket, _user: UserAttachment, _message: {
|
|
1459
1467
|
type: string;
|
|
1460
1468
|
[key: string]: unknown;
|
|
1461
1469
|
}): void;
|
|
1462
1470
|
protected onBinaryMessage(ws: WebSocket, user: UserAttachment, data: ArrayBuffer): void;
|
|
1463
|
-
protected onDisconnect(ws: WebSocket,
|
|
1471
|
+
protected onDisconnect(ws: WebSocket, _user: UserAttachment): void;
|
|
1464
1472
|
private handleSync;
|
|
1465
1473
|
private handleAwareness;
|
|
1466
1474
|
private readAwarenessUpdates;
|
|
@@ -1542,13 +1550,13 @@ declare abstract class GameRoom<E = Record<string, unknown>> extends BaseRoom<E>
|
|
|
1542
1550
|
*/
|
|
1543
1551
|
protected abstract onTick(state: Record<string, unknown>, inputs: GameInput[], tick: number): Record<string, unknown> | undefined | Promise<Record<string, unknown> | undefined>;
|
|
1544
1552
|
/** Called when a player connects */
|
|
1545
|
-
protected onPlayerJoin(
|
|
1553
|
+
protected onPlayerJoin(_player: Player): void;
|
|
1546
1554
|
/** Called when a player disconnects */
|
|
1547
|
-
protected onPlayerLeave(
|
|
1555
|
+
protected onPlayerLeave(_player: Player): void;
|
|
1548
1556
|
/** Called when the game starts */
|
|
1549
1557
|
protected onGameStart(): void;
|
|
1550
1558
|
/** Called when the game ends */
|
|
1551
|
-
protected onGameEnd(
|
|
1559
|
+
protected onGameEnd(_finalState: Record<string, unknown>): void;
|
|
1552
1560
|
/**
|
|
1553
1561
|
* Called once when the DO first hydrates persisted state from storage.
|
|
1554
1562
|
* Receives the parsed state blob as it was written by a previous build.
|
|
@@ -2822,10 +2830,10 @@ interface CronContext {
|
|
|
2822
2830
|
query(collection: string, opts?: {
|
|
2823
2831
|
where?: Record<string, unknown>;
|
|
2824
2832
|
limit?: number;
|
|
2825
|
-
}): Promise<
|
|
2826
|
-
create(collection: string, data: Record<string, unknown>): Promise<
|
|
2827
|
-
update(collection: string, recordId: string, data: Record<string, unknown>): Promise<
|
|
2828
|
-
delete(collection: string, recordId: string): Promise<
|
|
2833
|
+
}): Promise<unknown[]>;
|
|
2834
|
+
create(collection: string, data: Record<string, unknown>): Promise<unknown>;
|
|
2835
|
+
update(collection: string, recordId: string, data: Record<string, unknown>): Promise<unknown>;
|
|
2836
|
+
delete(collection: string, recordId: string): Promise<unknown>;
|
|
2829
2837
|
};
|
|
2830
2838
|
/**
|
|
2831
2839
|
* Call a platform integration endpoint (e.g. "openai/chat-completion",
|
|
@@ -2833,7 +2841,7 @@ interface CronContext {
|
|
|
2833
2841
|
* APP_OWNER_JWT the rest of the SDK uses for server-side billed calls.
|
|
2834
2842
|
*/
|
|
2835
2843
|
integrations: {
|
|
2836
|
-
call(endpoint: string, params?: Record<string, unknown>): Promise<
|
|
2844
|
+
call(endpoint: string, params?: Record<string, unknown>): Promise<unknown>;
|
|
2837
2845
|
};
|
|
2838
2846
|
/** App owner's user ID */
|
|
2839
2847
|
ownerUserId: string;
|
|
@@ -3003,7 +3011,8 @@ interface ScreenshotOptions {
|
|
|
3003
3011
|
}
|
|
3004
3012
|
interface ScreenshotEnv extends PlatformWorkerEnv {
|
|
3005
3013
|
APP_NAME: string;
|
|
3006
|
-
|
|
3014
|
+
/** Absent until the app's first deploy registers it — see appendAppIdentity. */
|
|
3015
|
+
APP_IDENTITY_TOKEN?: string;
|
|
3007
3016
|
}
|
|
3008
3017
|
interface ScreenshotResult {
|
|
3009
3018
|
/** PNG bytes. */
|
|
@@ -3455,8 +3464,7 @@ interface VerifiedAuth {
|
|
|
3455
3464
|
userId: string;
|
|
3456
3465
|
claims: JwtClaims;
|
|
3457
3466
|
}
|
|
3458
|
-
|
|
3459
|
-
}
|
|
3467
|
+
type VerifyResult = VerifiedAuth;
|
|
3460
3468
|
interface TokenDebugInfo {
|
|
3461
3469
|
iss?: string | null;
|
|
3462
3470
|
aud?: string | string[] | null;
|
|
@@ -3498,6 +3506,33 @@ declare function timingSafeEqualHex(a: string, b: string): Promise<boolean>;
|
|
|
3498
3506
|
|
|
3499
3507
|
declare function decodeJwtPayload(token: string | null | undefined): TokenDebugInfo | undefined;
|
|
3500
3508
|
|
|
3509
|
+
/**
|
|
3510
|
+
* Test-account identification, shared by every platform worker.
|
|
3511
|
+
*
|
|
3512
|
+
* Test accounts (created via `deepspace test-accounts`) are real Better Auth
|
|
3513
|
+
* users demarcated three ways, and a caller may present as any of them
|
|
3514
|
+
* depending on where the check runs:
|
|
3515
|
+
* - their email always ends with @deepspace.test (enforced at creation)
|
|
3516
|
+
* - their JWTs carry `isTestAccount: true` (minted by the auth-worker,
|
|
3517
|
+
* the source of truth)
|
|
3518
|
+
* - their billing profile's subscription tier is 'test' (mirrored by the
|
|
3519
|
+
* api-worker on every authenticated request)
|
|
3520
|
+
*
|
|
3521
|
+
* Gate anything a test account must not do with these helpers rather than
|
|
3522
|
+
* hand-rolled string comparisons, so the policy stays in one place. Prefer
|
|
3523
|
+
* checking the claim when a verified JWT is at hand, and the tier as the
|
|
3524
|
+
* fallback for persisted state that may outlive a claim (e.g. rows written
|
|
3525
|
+
* before a guard existed).
|
|
3526
|
+
*/
|
|
3527
|
+
|
|
3528
|
+
declare const TEST_ACCOUNT_EMAIL_SUFFIX = "@deepspace.test";
|
|
3529
|
+
/** True when the email belongs to a test account (case-insensitive). */
|
|
3530
|
+
declare function isTestAccountEmail(email: string | null | undefined): boolean;
|
|
3531
|
+
/** True when verified JWT claims identify the caller as a test account. */
|
|
3532
|
+
declare function isTestAccountClaims(claims: JwtClaims | Record<string, unknown> | null | undefined): boolean;
|
|
3533
|
+
/** True when a billing subscription tier marks a test account. */
|
|
3534
|
+
declare function isTestAccountTier(tier: string | null | undefined): boolean;
|
|
3535
|
+
|
|
3501
3536
|
interface DeepSpaceAuthConfig {
|
|
3502
3537
|
/** D1 database binding */
|
|
3503
3538
|
database: D1Database;
|
|
@@ -3539,6 +3574,7 @@ interface DeepSpaceAuthConfig {
|
|
|
3539
3574
|
declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.Auth<{
|
|
3540
3575
|
plugins: [{
|
|
3541
3576
|
id: "organization";
|
|
3577
|
+
version: string;
|
|
3542
3578
|
endpoints: better_auth_plugins.OrganizationEndpoints<better_auth_plugins.OrganizationOptions & {
|
|
3543
3579
|
teams: {
|
|
3544
3580
|
enabled: true;
|
|
@@ -3675,6 +3711,7 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3675
3711
|
INVITATION_NOT_FOUND: better_auth.RawError<"INVITATION_NOT_FOUND">;
|
|
3676
3712
|
YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION: better_auth.RawError<"YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION">;
|
|
3677
3713
|
EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION: better_auth.RawError<"EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION">;
|
|
3714
|
+
EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION: better_auth.RawError<"EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION">;
|
|
3678
3715
|
YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION: better_auth.RawError<"YOU_ARE_NOT_ALLOWED_TO_CANCEL_THIS_INVITATION">;
|
|
3679
3716
|
INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION: better_auth.RawError<"INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION">;
|
|
3680
3717
|
YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE: better_auth.RawError<"YOU_ARE_NOT_ALLOWED_TO_INVITE_USER_WITH_THIS_ROLE">;
|
|
@@ -3709,6 +3746,7 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3709
3746
|
ROLE_NAME_IS_ALREADY_TAKEN: better_auth.RawError<"ROLE_NAME_IS_ALREADY_TAKEN">;
|
|
3710
3747
|
CANNOT_DELETE_A_PRE_DEFINED_ROLE: better_auth.RawError<"CANNOT_DELETE_A_PRE_DEFINED_ROLE">;
|
|
3711
3748
|
ROLE_IS_ASSIGNED_TO_MEMBERS: better_auth.RawError<"ROLE_IS_ASSIGNED_TO_MEMBERS">;
|
|
3749
|
+
INVALID_TEAM_ID: better_auth.RawError<"INVALID_TEAM_ID">;
|
|
3712
3750
|
};
|
|
3713
3751
|
options: NoInfer<better_auth_plugins.OrganizationOptions & {
|
|
3714
3752
|
teams: {
|
|
@@ -3720,13 +3758,17 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3720
3758
|
}>;
|
|
3721
3759
|
}, {
|
|
3722
3760
|
id: "two-factor";
|
|
3761
|
+
version: string;
|
|
3723
3762
|
endpoints: {
|
|
3724
3763
|
enableTwoFactor: better_auth.StrictEndpoint<"/two-factor/enable", {
|
|
3725
3764
|
method: "POST";
|
|
3726
|
-
body:
|
|
3727
|
-
password:
|
|
3728
|
-
issuer:
|
|
3729
|
-
},
|
|
3765
|
+
body: zod.ZodObject<{
|
|
3766
|
+
password: zod.ZodOptional<zod.ZodString>;
|
|
3767
|
+
issuer: zod.ZodOptional<zod.ZodString>;
|
|
3768
|
+
}, zod_v4_core.$strip> | zod.ZodObject<{
|
|
3769
|
+
password: zod.ZodString;
|
|
3770
|
+
issuer: zod.ZodOptional<zod.ZodString>;
|
|
3771
|
+
}, zod_v4_core.$strip>;
|
|
3730
3772
|
use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
|
|
3731
3773
|
session: {
|
|
3732
3774
|
session: Record<string, any> & {
|
|
@@ -3787,9 +3829,11 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3787
3829
|
}>;
|
|
3788
3830
|
disableTwoFactor: better_auth.StrictEndpoint<"/two-factor/disable", {
|
|
3789
3831
|
method: "POST";
|
|
3790
|
-
body:
|
|
3791
|
-
password:
|
|
3792
|
-
},
|
|
3832
|
+
body: zod.ZodObject<{
|
|
3833
|
+
password: zod.ZodOptional<zod.ZodString>;
|
|
3834
|
+
}, zod_v4_core.$strip> | zod.ZodObject<{
|
|
3835
|
+
password: zod.ZodString;
|
|
3836
|
+
}, zod_v4_core.$strip>;
|
|
3793
3837
|
use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
|
|
3794
3838
|
session: {
|
|
3795
3839
|
session: Record<string, any> & {
|
|
@@ -3841,11 +3885,11 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3841
3885
|
}>;
|
|
3842
3886
|
verifyBackupCode: better_auth.StrictEndpoint<"/two-factor/verify-backup-code", {
|
|
3843
3887
|
method: "POST";
|
|
3844
|
-
body:
|
|
3845
|
-
code:
|
|
3846
|
-
disableSession:
|
|
3847
|
-
trustDevice:
|
|
3848
|
-
},
|
|
3888
|
+
body: zod.ZodObject<{
|
|
3889
|
+
code: zod.ZodString;
|
|
3890
|
+
disableSession: zod.ZodOptional<zod.ZodBoolean>;
|
|
3891
|
+
trustDevice: zod.ZodOptional<zod.ZodBoolean>;
|
|
3892
|
+
}, zod_v4_core.$strip>;
|
|
3849
3893
|
metadata: {
|
|
3850
3894
|
openapi: {
|
|
3851
3895
|
description: string;
|
|
@@ -3952,9 +3996,11 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
3952
3996
|
}>;
|
|
3953
3997
|
generateBackupCodes: better_auth.StrictEndpoint<"/two-factor/generate-backup-codes", {
|
|
3954
3998
|
method: "POST";
|
|
3955
|
-
body:
|
|
3956
|
-
password:
|
|
3957
|
-
},
|
|
3999
|
+
body: zod.ZodObject<{
|
|
4000
|
+
password: zod.ZodOptional<zod.ZodString>;
|
|
4001
|
+
}, zod_v4_core.$strip> | zod.ZodObject<{
|
|
4002
|
+
password: zod.ZodString;
|
|
4003
|
+
}, zod_v4_core.$strip>;
|
|
3958
4004
|
use: ((inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
|
|
3959
4005
|
session: {
|
|
3960
4006
|
session: Record<string, any> & {
|
|
@@ -4016,18 +4062,18 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4016
4062
|
}>;
|
|
4017
4063
|
viewBackupCodes: better_auth.StrictEndpoint<string, {
|
|
4018
4064
|
method: "POST";
|
|
4019
|
-
body:
|
|
4020
|
-
userId:
|
|
4021
|
-
},
|
|
4065
|
+
body: zod.ZodObject<{
|
|
4066
|
+
userId: zod.ZodCoercedString<unknown>;
|
|
4067
|
+
}, zod_v4_core.$strip>;
|
|
4022
4068
|
}, {
|
|
4023
4069
|
status: boolean;
|
|
4024
4070
|
backupCodes: string[];
|
|
4025
4071
|
}>;
|
|
4026
4072
|
sendTwoFactorOTP: better_auth.StrictEndpoint<"/two-factor/send-otp", {
|
|
4027
4073
|
method: "POST";
|
|
4028
|
-
body:
|
|
4029
|
-
trustDevice:
|
|
4030
|
-
},
|
|
4074
|
+
body: zod.ZodOptional<zod.ZodObject<{
|
|
4075
|
+
trustDevice: zod.ZodOptional<zod.ZodBoolean>;
|
|
4076
|
+
}, zod_v4_core.$strip>>;
|
|
4031
4077
|
metadata: {
|
|
4032
4078
|
openapi: {
|
|
4033
4079
|
summary: string;
|
|
@@ -4056,10 +4102,10 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4056
4102
|
}>;
|
|
4057
4103
|
verifyTwoFactorOTP: better_auth.StrictEndpoint<"/two-factor/verify-otp", {
|
|
4058
4104
|
method: "POST";
|
|
4059
|
-
body:
|
|
4060
|
-
code:
|
|
4061
|
-
trustDevice:
|
|
4062
|
-
},
|
|
4105
|
+
body: zod.ZodObject<{
|
|
4106
|
+
code: zod.ZodString;
|
|
4107
|
+
trustDevice: zod.ZodOptional<zod.ZodBoolean>;
|
|
4108
|
+
}, zod_v4_core.$strip>;
|
|
4063
4109
|
metadata: {
|
|
4064
4110
|
openapi: {
|
|
4065
4111
|
summary: string;
|
|
@@ -4145,9 +4191,9 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4145
4191
|
}>;
|
|
4146
4192
|
generateTOTP: better_auth.StrictEndpoint<string, {
|
|
4147
4193
|
method: "POST";
|
|
4148
|
-
body:
|
|
4149
|
-
secret:
|
|
4150
|
-
},
|
|
4194
|
+
body: zod.ZodObject<{
|
|
4195
|
+
secret: zod.ZodString;
|
|
4196
|
+
}, zod_v4_core.$strip>;
|
|
4151
4197
|
metadata: {
|
|
4152
4198
|
openapi: {
|
|
4153
4199
|
summary: string;
|
|
@@ -4199,9 +4245,11 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4199
4245
|
};
|
|
4200
4246
|
};
|
|
4201
4247
|
}>)[];
|
|
4202
|
-
body:
|
|
4203
|
-
password:
|
|
4204
|
-
},
|
|
4248
|
+
body: zod.ZodObject<{
|
|
4249
|
+
password: zod.ZodOptional<zod.ZodString>;
|
|
4250
|
+
}, zod_v4_core.$strip> | zod.ZodObject<{
|
|
4251
|
+
password: zod.ZodString;
|
|
4252
|
+
}, zod_v4_core.$strip>;
|
|
4205
4253
|
metadata: {
|
|
4206
4254
|
openapi: {
|
|
4207
4255
|
summary: string;
|
|
@@ -4230,10 +4278,10 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4230
4278
|
}>;
|
|
4231
4279
|
verifyTOTP: better_auth.StrictEndpoint<"/two-factor/verify-totp", {
|
|
4232
4280
|
method: "POST";
|
|
4233
|
-
body:
|
|
4234
|
-
code:
|
|
4235
|
-
trustDevice:
|
|
4236
|
-
},
|
|
4281
|
+
body: zod.ZodObject<{
|
|
4282
|
+
code: zod.ZodString;
|
|
4283
|
+
trustDevice: zod.ZodOptional<zod.ZodBoolean>;
|
|
4284
|
+
}, zod_v4_core.$strip>;
|
|
4237
4285
|
metadata: {
|
|
4238
4286
|
openapi: {
|
|
4239
4287
|
summary: string;
|
|
@@ -4279,6 +4327,7 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4279
4327
|
matcher(context: better_auth.HookEndpointContext): boolean;
|
|
4280
4328
|
handler: (inputContext: better_auth.MiddlewareInputContext<better_auth.MiddlewareOptions>) => Promise<{
|
|
4281
4329
|
twoFactorRedirect: boolean;
|
|
4330
|
+
twoFactorMethods: string[];
|
|
4282
4331
|
} | undefined>;
|
|
4283
4332
|
}[];
|
|
4284
4333
|
};
|
|
@@ -4316,6 +4365,25 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4316
4365
|
};
|
|
4317
4366
|
index: true;
|
|
4318
4367
|
};
|
|
4368
|
+
verified: {
|
|
4369
|
+
type: "boolean";
|
|
4370
|
+
required: false;
|
|
4371
|
+
defaultValue: true;
|
|
4372
|
+
input: false;
|
|
4373
|
+
};
|
|
4374
|
+
failedVerificationCount: {
|
|
4375
|
+
type: "number";
|
|
4376
|
+
required: false;
|
|
4377
|
+
defaultValue: number;
|
|
4378
|
+
input: false;
|
|
4379
|
+
returned: false;
|
|
4380
|
+
};
|
|
4381
|
+
lockedUntil: {
|
|
4382
|
+
type: "date";
|
|
4383
|
+
required: false;
|
|
4384
|
+
input: false;
|
|
4385
|
+
returned: false;
|
|
4386
|
+
};
|
|
4319
4387
|
};
|
|
4320
4388
|
};
|
|
4321
4389
|
};
|
|
@@ -4333,6 +4401,7 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
|
|
|
4333
4401
|
INVALID_BACKUP_CODE: better_auth.RawError<"INVALID_BACKUP_CODE">;
|
|
4334
4402
|
INVALID_CODE: better_auth.RawError<"INVALID_CODE">;
|
|
4335
4403
|
TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE: better_auth.RawError<"TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE">;
|
|
4404
|
+
ACCOUNT_TEMPORARILY_LOCKED: better_auth.RawError<"ACCOUNT_TEMPORARILY_LOCKED">;
|
|
4336
4405
|
INVALID_TWO_FACTOR_COOKIE: better_auth.RawError<"INVALID_TWO_FACTOR_COOKIE">;
|
|
4337
4406
|
};
|
|
4338
4407
|
}];
|
|
@@ -4370,4 +4439,4 @@ type DeepSpaceAuth = ReturnType<typeof createDeepSpaceAuth>;
|
|
|
4370
4439
|
/** Collections that bypass schema checks (permissive access) */
|
|
4371
4440
|
declare const SYSTEM_COLLECTIONS: Set<string>;
|
|
4372
4441
|
|
|
4373
|
-
export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, 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, Awareness, type AwarenessState, type AwarenessStates, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, type BaseMessage, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, 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, 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, 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, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_DEFAULT, RecordRoom, type RecordRoomConfig, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, SYSTEM_COLLECTIONS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotOptions, type ScreenshotResult, type ServerMessage, type SharedConnection, type StoredRecord, type Summarizer, type SyncResult, 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, 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, handleSyncMessage, hasContent, isAutoProvision, isOwner, lintSchema, loadMessages, makeDefaultSummarizer, meterAi, meterUsage, meterVectorize, noopPermissionContext, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, readVarUint, readVarUint8Array, resolveAppName, resolveColumn, rowToData, runMigrations, serverBuild, timingSafeEqualHex, toUint8Array, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema, writeVarUint, writeVarUint8Array };
|
|
4442
|
+
export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, 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, Awareness, type AwarenessState, type AwarenessStates, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, type BaseMessage, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, 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, 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, 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, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_DEFAULT, RecordRoom, type RecordRoomConfig, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, SYSTEM_COLLECTIONS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotOptions, 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, 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, handleSyncMessage, hasContent, isAutoProvision, isOwner, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, lintSchema, loadMessages, makeDefaultSummarizer, meterAi, meterUsage, meterVectorize, noopPermissionContext, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, readVarUint, readVarUint8Array, resolveAppName, resolveColumn, rowToData, runMigrations, serverBuild, timingSafeEqualHex, toUint8Array, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema, writeVarUint, writeVarUint8Array };
|