@vryzel/file-next 0.4.1 → 0.4.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/result.ts","../../src/errors/mappers.ts","../../src/errors/index.ts","../../src/types/branded.ts","../../src/sync/write-through.ts"],"names":["err"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Discriminated `Result<T, E>` for typed error returns.\n *\n * Why Result over throw at boundaries:\n * - No `any` at the call site (vs try/catch which loses the type).\n * - `switch (r.ok)` narrows the type in consumer code.\n * - The wire shape `{ ok, value | error }` is JSON-serializable,\n * so it survives the RSC boundary without an extra DTO.\n * - Helpers (`map`, `andThen`, `unwrap`) make the common shapes\n * (chain, bail-out, recover) terse and exhaustive.\n *\n * The default error type is `FileSystemError` (see `@/errors`).\n * Consumers can specialize: `Result<User, ZodError>`.\n *\n * All helpers are pure functions; they do NOT allocate closures in\n * hot paths beyond what the spec demands (no `try`/`catch` wrapping).\n */\n\nimport { FileSystemError } from \"@/errors\";\n\nexport type Result<T, E = FileSystemError> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\nexport const map = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => U,\n): Result<U, E> => (r.ok ? ok(f(r.value)) : r);\n\nexport const mapErr = <T, E, F>(\n r: Result<T, E>,\n f: (e: E) => F,\n): Result<T, F> => (r.ok ? r : err(f(r.error)));\n\nexport const andThen = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => Result<U, E>,\n): Result<U, E> => (r.ok ? f(r.value) : r);\n\nexport const unwrap = <T, E>(r: Result<T, E>): T => {\n if (r.ok) return r.value;\n throw r.error;\n};\n\nexport const unwrapOr = <T, E>(r: Result<T, E>, fallback: T): T =>\n r.ok ? r.value : fallback;\n","/**\n * Upstream error mappers for FileSystemError.\n *\n * Each mapper is a pure function `(*unknown) -> FileSystemError`.\n * The class re-exposes them as static methods (FileSystemError.fromAws\n * etc.) so callers can pick the import style that fits.\n *\n * Mapping strategy:\n * 1. If the input is already a FileSystemError, return it as-is\n * (we never re-wrap our own errors).\n * 2. Try the most specific signal first: S3 `name`, Postgres\n * SQLSTATE, SQLite extended code.\n * 3. Fall back to the HTTP status code (AWS SDK v3 exposes\n * `$metadata.httpStatusCode`).\n * 4. Last resort: InternalError, retryable, with the original\n * payload in `cause`.\n *\n * Provider-specific codes are preserved on `cause.code` (e.g. S3\n * \"NoSuchKey\", Postgres \"23505\") so callers can still branch on\n * them while the top-level `code` stays in the 11-code spec catalog.\n *\n * Mapping notes (post-C' merge, see\n * `sdd/file-next/decisions/error-codes-deviation`):\n * - S3 `SlowDown` -> QuotaExceeded (broader than RateLimited;\n * SlowDown means reduce request rate, which\n * is conceptually quota pressure, not\n * throttling of a single call).\n * - S3 `BadDigest` -> ChecksumMismatch (checksum verified by\n * S3 on upload did not match the client).\n * - HTTP 429 -> RateLimited (was QuotaExceeded in the\n * pre-C' catalog; RateLimited is the more\n * specific code for throttling responses).\n * - HTTP 408 -> NetworkError (transient transport error).\n * - HTTP 400 / Postgres 23514 / S3 InvalidRequest\n * -> fall through to the 4xx branch (no\n * top-level 400 code in the C' catalog;\n * these inputs are usually caught by the\n * name/SQLSTATE mapping first anyway).\n */\n\nimport { FileSystemError, type FileSystemErrorCode } from \"./index\";\n\n/* ---------------------------------------------------------------- *\n * Mapping tables (private) *\n * ---------------------------------------------------------------- */\n\ninterface CodeMapping {\n code: FileSystemErrorCode;\n retryable: boolean;\n}\n\nconst HTTP_STATUS_TO_CODE: Readonly<Record<number, CodeMapping>> = {\n 401: { code: \"Unauthorized\", retryable: false },\n 403: { code: \"Forbidden\", retryable: false },\n 404: { code: \"NotFound\", retryable: false },\n 408: { code: \"NetworkError\", retryable: true },\n 409: { code: \"Conflict\", retryable: false },\n 413: { code: \"PayloadTooLarge\", retryable: false },\n 415: { code: \"UnsupportedMediaType\", retryable: false },\n 429: { code: \"RateLimited\", retryable: true },\n};\n\nconst AWS_NAME_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n NoSuchKey: { code: \"NotFound\", retryable: false },\n NoSuchBucket: { code: \"NotFound\", retryable: false },\n // v0.2 multipart: unknown/aborted/expired uploadId.\n NoSuchUpload: { code: \"NotFound\", retryable: false },\n AccessDenied: { code: \"Forbidden\", retryable: false },\n SlowDown: { code: \"QuotaExceeded\", retryable: true },\n BadDigest: { code: \"ChecksumMismatch\", retryable: true },\n XAmzContentSHA256Mismatch: { code: \"ChecksumMismatch\", retryable: true },\n NetworkingError: { code: \"NetworkError\", retryable: true },\n TimeoutError: { code: \"NetworkError\", retryable: true },\n};\n\nconst PG_SQLSTATE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n \"23505\": { code: \"Conflict\", retryable: false },\n};\n\nconst SQLITE_CODE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n SQLITE_CONSTRAINT_UNIQUE: { code: \"Conflict\", retryable: false },\n SQLITE_CONSTRAINT_PRIMARYKEY: { code: \"Conflict\", retryable: false },\n};\n\n/* ---------------------------------------------------------------- *\n * Public mappers *\n * ---------------------------------------------------------------- */\n\nconst toCause = (code: string, message: string, extra?: Record<string, unknown>) => ({\n code,\n message,\n ...(extra ?? {}),\n});\n\nconst fallback = (err: unknown): FileSystemError =>\n new FileSystemError({\n code: \"InternalError\",\n message: err instanceof Error ? err.message : String(err),\n retryable: true,\n cause: toCause(\n \"Unknown\",\n err instanceof Error ? err.message : String(err),\n ),\n });\n\nexport const fromAws = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const awsErr = err as {\n name?: unknown;\n message?: unknown;\n $metadata?: { httpStatusCode?: unknown };\n };\n const name = typeof awsErr.name === \"string\" ? awsErr.name : undefined;\n const message =\n typeof awsErr.message === \"string\" ? awsErr.message : `AWS error: ${name ?? \"unknown\"}`;\n const status =\n typeof awsErr.$metadata?.httpStatusCode === \"number\"\n ? awsErr.$metadata.httpStatusCode\n : undefined;\n\n const cause = toCause(\n name ?? (status !== undefined ? String(status) : \"Unknown\"),\n message,\n status !== undefined ? { httpStatusCode: status } : undefined,\n );\n\n // 1) name-based mapping wins (more specific than HTTP status)\n if (name && name in AWS_NAME_TO_CODE) {\n const m = AWS_NAME_TO_CODE[name]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 2) HTTP status mapping\n if (status !== undefined && status in HTTP_STATUS_TO_CODE) {\n const m = HTTP_STATUS_TO_CODE[status]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 3) 5xx bucket\n if (status !== undefined && status >= 500 && status < 600) {\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n }\n\n // 4) anything else 4xx-shaped\n if (status !== undefined && status >= 400 && status < 500) {\n return new FileSystemError({ code: \"Forbidden\", message, retryable: false, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromPg = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const pgErr = err as { code?: unknown; message?: unknown };\n const sqlstate = typeof pgErr.code === \"string\" ? pgErr.code : undefined;\n const message =\n typeof pgErr.message === \"string\" ? pgErr.message : `Postgres error: ${sqlstate ?? \"unknown\"}`;\n const cause = toCause(sqlstate ?? \"Unknown\", message);\n\n if (sqlstate && sqlstate in PG_SQLSTATE_TO_CODE) {\n const m = PG_SQLSTATE_TO_CODE[sqlstate]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromSqlite = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const sqlErr = err as { code?: unknown; message?: unknown };\n const code = typeof sqlErr.code === \"string\" ? sqlErr.code : undefined;\n const message =\n typeof sqlErr.message === \"string\" ? sqlErr.message : `SQLite error: ${code ?? \"unknown\"}`;\n const cause = toCause(code ?? \"Unknown\", message);\n\n if (code && code in SQLITE_CODE_TO_CODE) {\n const m = SQLITE_CODE_TO_CODE[code]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n","/**\n * FileSystemError — the single error class every adapter, store,\n * server action, and route handler in `file-next` returns or throws.\n *\n * Spec reference: requirement \"FileSystemError discriminated union\"\n * in `sdd/file-next/spec`. The 11 codes are the CLOSED set; any\n * provider-specific code (e.g. S3 `NoSuchKey`, Postgres `23505`) is\n * preserved on `cause.code` so callers can still distinguish upstream\n * reasons while the top-level `code` stays in the catalog.\n *\n * The catalog is a merge of spec + impl: the 6 fixed codes\n * (NotFound, Forbidden, Conflict, QuotaExceeded, NetworkError,\n * InternalError) are non-negotiable; the remaining 5 keep the wire\n * aligned with both the HTTP boundary (route handlers map the\n * top-level `code` to a status directly) and the storage boundary\n * (`RateLimited` and `ChecksumMismatch` carry semantics that have\n * no natural HTTP equivalent). See\n * `sdd/file-next/decisions/error-codes-deviation` for the\n * deviation log and rationale.\n *\n * Retryability table is the design's `error-mapping` excerpt; see\n * `sdd/file-next/design` §C. Any future code MUST add an entry in\n * `RETRYABLE_BY_CODE` (the catalog test enforces this).\n *\n * The placeholder from T-006 is replaced by this file in T-007a.\n * The upstream mappers (fromAws / fromPg / fromSqlite) land in T-007b\n * in `mappers.ts`.\n */\n\nexport const FILE_SYSTEM_ERROR_CODES = [\n \"NotFound\",\n \"Forbidden\",\n \"Conflict\",\n \"QuotaExceeded\",\n \"NetworkError\",\n \"InternalError\",\n \"Unauthorized\",\n \"PayloadTooLarge\",\n \"UnsupportedMediaType\",\n \"RateLimited\",\n \"ChecksumMismatch\",\n] as const satisfies readonly string[];\n\nexport type FileSystemErrorCode = (typeof FILE_SYSTEM_ERROR_CODES)[number];\n\nexport const RETRYABLE_BY_CODE: Readonly<Record<FileSystemErrorCode, boolean>> = {\n NotFound: false,\n Forbidden: false,\n Conflict: false,\n QuotaExceeded: true,\n NetworkError: true,\n InternalError: true,\n Unauthorized: false,\n PayloadTooLarge: false,\n UnsupportedMediaType: false,\n RateLimited: true,\n ChecksumMismatch: true,\n};\n\nexport interface FileSystemErrorOptions {\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport interface FileSystemErrorJson {\n name: string;\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport class FileSystemError extends Error {\n readonly code: FileSystemErrorCode;\n readonly retryable: boolean;\n override readonly cause?: { code: string; message: string; [k: string]: unknown };\n\n constructor(opts: FileSystemErrorOptions) {\n super(opts.message);\n this.name = \"FileSystemError\";\n this.code = opts.code;\n this.retryable = opts.retryable;\n if (opts.cause !== undefined) {\n this.cause = opts.cause;\n }\n }\n\n /**\n * Stable JSON shape for RSC pass-through. Error.prototype.message\n * is non-enumerable, so plain `JSON.stringify(err)` would emit `{}`\n * and lose the message + code + retryable flag. `cause` is omitted\n * entirely (not set to undefined) when absent so the shape stays\n * stable for hash-based caches.\n */\n toJSON(): FileSystemErrorJson {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n };\n }\n\n /**\n * Mappers from upstream error shapes (AWS SDK v3, node-postgres,\n * better-sqlite3) to FileSystemError. See `./mappers.ts` for the\n * mapping tables. Re-exposed as static methods so callers can pick\n * the import style that fits; the free functions are the canonical\n * implementation.\n */\n static fromAws(err: unknown): FileSystemError {\n // Lazy import via the runtime binding avoids the static-field\n // circular-dep trap in ESM. The mapper file imports this class\n // for instanceof checks; we look up the function at call time.\n return _fromAws(err);\n }\n\n static fromPg(err: unknown): FileSystemError {\n return _fromPg(err);\n }\n\n static fromSqlite(err: unknown): FileSystemError {\n return _fromSqlite(err);\n }\n}\n\n// Imported here as bindings (not values) so the static methods above\n// can resolve them lazily. The actual implementation lives in mappers.ts.\nimport { fromAws as _fromAws, fromPg as _fromPg, fromSqlite as _fromSqlite } from \"./mappers\";\nexport { fromAws, fromPg, fromSqlite } from \"./mappers\";\n","/**\n * Branded string types and their constructors/guards.\n *\n * Brands are TypeScript-only fictions: a `Path` and an `S3Key` are\n * both strings at runtime, but the type system treats them as\n * distinct nominal types so the compiler catches accidental\n * cross-assignment (e.g. passing an S3Key where a TenantId is\n * expected).\n *\n * Conventions:\n * - `as*` is a zero-cost cast: trust the caller, brand the value.\n * Use it at trust boundaries you have already validated.\n * - `assert*` is a runtime guard: throws TypeError on invalid\n * input. Use it at the edge (parsing user/env input).\n *\n * Validation rules are intentionally minimal in v0.1 and can be\n * tightened as the spec evolves. None of them touch the network or\n * allocate; they are safe in hot paths.\n */\n\nexport type Path = string & { readonly __brand: \"Path\" };\nexport type Prefix = string & { readonly __brand: \"Prefix\" };\nexport type S3Key = string & { readonly __brand: \"S3Key\" };\nexport type TenantId = string & { readonly __brand: \"TenantId\" };\nexport type UserId = string & { readonly __brand: \"UserId\" };\n\n/**\n * POSIX file path. Non-empty, '/' is allowed as the root.\n */\nexport const asPath = (s: string): Path => s as Path;\nexport const assertPath = (s: string): Path => {\n if (s.length === 0) {\n throw new TypeError(\"Path must be a non-empty string\");\n }\n return s as Path;\n};\n\n/**\n * S3 prefix. Empty string is the root prefix. Non-empty prefixes\n * MUST end with '/' so concatenation with a key never produces\n * 'usersfile.jpg' by accident.\n */\nexport const asPrefix = (s: string): Prefix => s as Prefix;\nexport const assertPrefix = (s: string): Prefix => {\n if (s.length > 0 && !s.endsWith(\"/\")) {\n throw new TypeError(\n `Prefix must end with \"/\" or be empty: ${JSON.stringify(s)}`,\n );\n }\n return s as Prefix;\n};\n\n/**\n * S3 object key. No leading slash, no empty segments, no '..' hops.\n */\nexport const asS3Key = (s: string): S3Key => s as S3Key;\nexport const assertS3Key = (s: string): S3Key => {\n if (s.length === 0) {\n throw new TypeError(\"S3Key must be a non-empty string\");\n }\n if (s.startsWith(\"/\")) {\n throw new TypeError(\n `S3Key must not start with a slash: ${JSON.stringify(s)}`,\n );\n }\n if (s.includes(\"..\")) {\n throw new TypeError(\n `S3Key must not contain '..' segments: ${JSON.stringify(s)}`,\n );\n }\n return s as S3Key;\n};\n\n/**\n * Tenant identifier. Alphanumerics, dashes, underscores only.\n */\nexport const asTenantId = (s: string): TenantId => s as TenantId;\nexport const assertTenantId = (s: string): TenantId => {\n if (s.length === 0 || !/^[a-zA-Z0-9_-]+$/.test(s)) {\n throw new TypeError(`Invalid TenantId: ${JSON.stringify(s)}`);\n }\n return s as TenantId;\n};\n\n/**\n * Opaque user identifier. Non-empty; the format is provider-defined.\n */\nexport const asUserId = (s: string): UserId => s as UserId;\nexport const assertUserId = (s: string): UserId => {\n if (s.length === 0) {\n throw new TypeError(\"UserId must be a non-empty string\");\n }\n return s as UserId;\n};\n","/**\n * WriteThrough — keeps object storage and the metadata tree in lockstep.\n *\n * Object keys are the node UUID. Rename/move stay metadata-only.\n * Copy writes a new object under a new UUID.\n */\nimport { ok, err, type Result } from \"@/types/result\";\nimport { FileSystemError } from \"@/errors\";\nimport { asS3Key, asTenantId, asUserId, type S3Key, type TenantId } from \"@/types/branded\";\nimport type { FileSystem } from \"../storage/filesystem\";\nimport type { MetadataStore, FileNode, CreateNodeInput } from \"../metadata/store\";\n\nexport type OrphanOp = \"delete\" | \"restore\";\n\nexport interface PendingOrphan {\n readonly id: string;\n readonly tenantId: TenantId;\n readonly s3Key: S3Key;\n readonly op: OrphanOp;\n readonly createdAt: Date;\n readonly reason: string;\n readonly nodeId?: string;\n}\n\nexport interface WriteThroughFileInput {\n readonly tenantId: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly body: Uint8Array | ReadableStream<Uint8Array>;\n readonly contentType: string;\n readonly metadata?: Readonly<Record<string, string>>;\n readonly ownerId?: string;\n readonly maxBytes?: number;\n readonly id?: string;\n}\n\nexport interface DeleteThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly recursive?: boolean;\n}\n\nexport interface CopyThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly newParentId: string | null;\n readonly newName?: string;\n}\n\nexport interface ConfirmUploadInput {\n readonly tenantId: string;\n readonly id: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly contentType?: string;\n readonly size?: number;\n readonly ownerId?: string;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface ReconcileReport {\n readonly orphans: ReadonlyArray<PendingOrphan>;\n readonly scanned: number;\n readonly missingInS3: ReadonlyArray<string>;\n readonly orphansInS3: ReadonlyArray<string>;\n readonly fixed: number;\n}\n\nconst bootedTenants = new Set<string>();\n\nexport const __resetDrainState = (): void => {\n bootedTenants.clear();\n};\n\nconst newId = (): string =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : `node-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n\nconst scopedFs = (fs: FileSystem, tenantId: string): FileSystem =>\n fs.tenantId === tenantId ? fs : fs.forTenant(tenantId);\n\nconst bodySize = (body: WriteThroughFileInput[\"body\"]): number => {\n const maybe = body as { byteLength?: number };\n return typeof maybe.byteLength === \"number\" ? maybe.byteLength : 0;\n};\n\nconst drainPendingOrphansFor = async (\n fs: FileSystem,\n store: MetadataStore,\n tenantId: TenantId,\n): Promise<void> => {\n if (bootedTenants.has(tenantId)) return;\n bootedTenants.add(tenantId);\n const result = await store.listPendingOrphans({ tenantId });\n if (!result.ok) return;\n const adapter = scopedFs(fs, tenantId).adapter;\n for (const orphan of result.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n await store.deleteOrphan({ tenantId, id: orphan.id });\n }\n};\n\nexport const createWriteThrough = (\n fs: FileSystem,\n store: MetadataStore,\n): {\n writeThroughFile: (\n input: WriteThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n deleteThroughFile: (\n input: DeleteThroughFileInput,\n ) => Promise<Result<void, FileSystemError>>;\n copyThroughFile: (\n input: CopyThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n confirmUpload: (\n input: ConfirmUploadInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n reconcile: (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }) => Promise<Result<ReconcileReport, FileSystemError>>;\n getOrphans: () => ReadonlyArray<PendingOrphan>;\n} => {\n const writeThroughFile = async (\n input: WriteThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const id = input.id ?? newId();\n const s3Key = asS3Key(id);\n const calcSize = bodySize(input.body);\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + calcSize > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n const w = await adapter.write({\n key: s3Key,\n body: input.body,\n contentType: input.contentType,\n metadata: input.metadata,\n });\n if (!w.ok) return w;\n\n const ownerId = input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\");\n const createInput: CreateNodeInput = {\n id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size: calcSize,\n mimeType: input.contentType,\n s3Key,\n ownerId,\n metadata: input.metadata,\n };\n const c = await store.createNode(createInput);\n if (!c.ok) {\n const enqueue = await store.enqueueOrphan({\n tenantId,\n s3Key,\n reason: c.error.message,\n });\n if (!enqueue.ok) {\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded, metadata insert failed, and orphan enqueue failed: ${enqueue.error.message}; original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n await adapter.delete({ key: s3Key });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded but metadata insert failed; orphan logged for reconcile. S3 cleanup attempted. Original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n\n return ok(c.value);\n };\n\n const deleteThroughFile = async (\n input: DeleteThroughFileInput,\n ): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const node = g.value;\n const d = await store.deleteNode({\n tenantId,\n id: input.id,\n recursive: input.recursive,\n });\n if (!d.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key || node.id),\n metadataId: input.id,\n reason: d.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata soft-delete failed; orphan logged. Original: ${d.error.message}`,\n retryable: false,\n }),\n );\n }\n\n if (node.kind === \"file\" && node.s3Key) {\n const del = await adapter.delete({ key: asS3Key(node.s3Key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key),\n metadataId: input.id,\n reason: del.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata deleted but S3 delete failed; orphan logged. Original: ${del.error.message}`,\n retryable: false,\n }),\n );\n }\n }\n\n return ok(undefined);\n };\n\n const copyThroughFile = async (\n input: CopyThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const src = g.value;\n const id = newId();\n if (src.kind === \"file\" && src.s3Key) {\n const copied = await adapter.copy({\n sourceKey: asS3Key(src.s3Key),\n destinationKey: asS3Key(id),\n });\n if (!copied.ok) return copied;\n }\n return store.createNode({\n id,\n tenantId,\n parentId: input.newParentId,\n name: input.newName ?? src.name,\n kind: src.kind,\n size: src.size,\n mimeType: src.mimeType,\n s3Key: src.kind === \"file\" ? id : \"\",\n ownerId: src.ownerId,\n metadata: src.metadata,\n });\n };\n\n const confirmUpload = async (\n input: ConfirmUploadInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const existing = await store.findByS3Key({ tenantId, s3Key: input.id });\n if (existing.ok && existing.value) return ok(existing.value);\n\n const st = await adapter.stat({ key: asS3Key(input.id) });\n const size = st.ok ? st.value.size : (input.size ?? 0);\n const mimeType = input.contentType ?? (st.ok ? st.value.contentType : \"\");\n if (!st.ok && input.size === undefined) return st;\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + size > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n return store.createNode({\n id: input.id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size,\n mimeType,\n s3Key: input.id,\n ownerId: input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\"),\n metadata: input.metadata,\n });\n };\n\n const reconcile = async (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }): Promise<Result<ReconcileReport, FileSystemError>> => {\n if (!input?.tenantId) {\n return ok({\n orphans: [],\n scanned: 0,\n missingInS3: [],\n orphansInS3: [],\n fixed: 0,\n });\n }\n const tenantId = asTenantId(input.tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const dryRun = input.dryRun === true;\n let fixed = 0;\n\n const pending = await store.listPendingOrphans({ tenantId });\n if (!pending.ok) return pending;\n if (!dryRun) {\n for (const orphan of pending.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n const del = await store.deleteOrphan({ tenantId, id: orphan.id });\n if (del.ok) fixed += 1;\n }\n }\n\n const keys = await store.scanFileKeys({ tenantId });\n if (!keys.ok) return keys;\n const missingInS3: string[] = [];\n for (const row of keys.value) {\n const exists = await adapter.exists({ key: asS3Key(row.s3Key) });\n if (exists.ok && !exists.value.exists) missingInS3.push(row.s3Key);\n }\n\n const listed = await adapter.list({ prefix: \"\" as never });\n const orphansInS3: string[] = [];\n if (listed.ok) {\n const known = new Set(keys.value.map((k) => k.s3Key));\n for (const item of listed.value.items) {\n if (!known.has(item.key)) orphansInS3.push(item.key);\n }\n }\n\n return ok({\n orphans: pending.value.map((orphan) => ({\n id: orphan.id,\n tenantId: orphan.tenantId,\n s3Key: orphan.s3Key,\n op: \"delete\" as const,\n createdAt: orphan.createdAt,\n reason: orphan.reason,\n nodeId: orphan.metadataId ?? undefined,\n })),\n scanned: keys.value.length,\n missingInS3,\n orphansInS3,\n fixed,\n });\n };\n\n return {\n writeThroughFile,\n deleteThroughFile,\n copyThroughFile,\n confirmUpload,\n reconcile,\n getOrphans: () => [],\n };\n};\n"]}
1
+ {"version":3,"sources":["../../src/types/result.ts","../../src/errors/mappers.ts","../../src/errors/index.ts","../../src/types/branded.ts","../../src/sync/write-through.ts"],"names":["err"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Discriminated `Result<T, E>` for typed error returns.\n *\n * Why Result over throw at boundaries:\n * - No `any` at the call site (vs try/catch which loses the type).\n * - `switch (r.ok)` narrows the type in consumer code.\n * - The wire shape `{ ok, value | error }` is JSON-serializable,\n * so it survives the RSC boundary without an extra DTO.\n * - Helpers (`map`, `andThen`, `unwrap`) make the common shapes\n * (chain, bail-out, recover) terse and exhaustive.\n *\n * The default error type is `FileSystemError` (see `@/errors`).\n * Consumers can specialize: `Result<User, ZodError>`.\n *\n * All helpers are pure functions; they do NOT allocate closures in\n * hot paths beyond what the spec demands (no `try`/`catch` wrapping).\n */\n\nimport { FileSystemError } from \"@/errors\";\n\nexport type Result<T, E = FileSystemError> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\nexport const map = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => U,\n): Result<U, E> => (r.ok ? ok(f(r.value)) : r);\n\nexport const mapErr = <T, E, F>(\n r: Result<T, E>,\n f: (e: E) => F,\n): Result<T, F> => (r.ok ? r : err(f(r.error)));\n\nexport const andThen = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => Result<U, E>,\n): Result<U, E> => (r.ok ? f(r.value) : r);\n\nexport const unwrap = <T, E>(r: Result<T, E>): T => {\n if (r.ok) return r.value;\n throw r.error;\n};\n\nexport const unwrapOr = <T, E>(r: Result<T, E>, fallback: T): T =>\n r.ok ? r.value : fallback;\n","/**\n * Upstream error mappers for FileSystemError.\n *\n * Each mapper is a pure function `(*unknown) -> FileSystemError`.\n * The class re-exposes them as static methods (FileSystemError.fromAws\n * etc.) so callers can pick the import style that fits.\n *\n * Mapping strategy:\n * 1. If the input is already a FileSystemError, return it as-is\n * (we never re-wrap our own errors).\n * 2. Try the most specific signal first: S3 `name`, Postgres\n * SQLSTATE, SQLite extended code.\n * 3. Fall back to the HTTP status code (AWS SDK v3 exposes\n * `$metadata.httpStatusCode`).\n * 4. Last resort: InternalError, retryable, with the original\n * payload in `cause`.\n *\n * Provider-specific codes are preserved on `cause.code` (e.g. S3\n * \"NoSuchKey\", Postgres \"23505\") so callers can still branch on\n * them while the top-level `code` stays in the 11-code spec catalog.\n *\n * Mapping notes (post-C' merge, see\n * `sdd/file-next/decisions/error-codes-deviation`):\n * - S3 `SlowDown` -> QuotaExceeded (broader than RateLimited;\n * SlowDown means reduce request rate, which\n * is conceptually quota pressure, not\n * throttling of a single call).\n * - S3 `BadDigest` -> ChecksumMismatch (checksum verified by\n * S3 on upload did not match the client).\n * - HTTP 429 -> RateLimited (was QuotaExceeded in the\n * pre-C' catalog; RateLimited is the more\n * specific code for throttling responses).\n * - HTTP 408 -> NetworkError (transient transport error).\n * - HTTP 400 / Postgres 23514 / S3 InvalidRequest\n * -> fall through to the 4xx branch (no\n * top-level 400 code in the C' catalog;\n * these inputs are usually caught by the\n * name/SQLSTATE mapping first anyway).\n */\n\nimport { FileSystemError, type FileSystemErrorCode } from \"./index\";\n\n/* ---------------------------------------------------------------- *\n * Mapping tables (private) *\n * ---------------------------------------------------------------- */\n\ninterface CodeMapping {\n code: FileSystemErrorCode;\n retryable: boolean;\n}\n\nconst HTTP_STATUS_TO_CODE: Readonly<Record<number, CodeMapping>> = {\n 401: { code: \"Unauthorized\", retryable: false },\n 403: { code: \"Forbidden\", retryable: false },\n 404: { code: \"NotFound\", retryable: false },\n 408: { code: \"NetworkError\", retryable: true },\n 409: { code: \"Conflict\", retryable: false },\n 413: { code: \"PayloadTooLarge\", retryable: false },\n 415: { code: \"UnsupportedMediaType\", retryable: false },\n 429: { code: \"RateLimited\", retryable: true },\n};\n\nconst AWS_NAME_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n NoSuchKey: { code: \"NotFound\", retryable: false },\n NoSuchBucket: { code: \"NotFound\", retryable: false },\n // v0.2 multipart: unknown/aborted/expired uploadId.\n NoSuchUpload: { code: \"NotFound\", retryable: false },\n AccessDenied: { code: \"Forbidden\", retryable: false },\n SlowDown: { code: \"QuotaExceeded\", retryable: true },\n BadDigest: { code: \"ChecksumMismatch\", retryable: true },\n XAmzContentSHA256Mismatch: { code: \"ChecksumMismatch\", retryable: true },\n NetworkingError: { code: \"NetworkError\", retryable: true },\n TimeoutError: { code: \"NetworkError\", retryable: true },\n};\n\nconst PG_SQLSTATE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n \"23505\": { code: \"Conflict\", retryable: false },\n};\n\nconst SQLITE_CODE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n SQLITE_CONSTRAINT_UNIQUE: { code: \"Conflict\", retryable: false },\n SQLITE_CONSTRAINT_PRIMARYKEY: { code: \"Conflict\", retryable: false },\n};\n\n/* ---------------------------------------------------------------- *\n * Public mappers *\n * ---------------------------------------------------------------- */\n\nconst toCause = (code: string, message: string, extra?: Record<string, unknown>) => ({\n code,\n message,\n ...(extra ?? {}),\n});\n\nconst fallback = (err: unknown): FileSystemError =>\n new FileSystemError({\n code: \"InternalError\",\n message: err instanceof Error ? err.message : String(err),\n retryable: true,\n cause: toCause(\n \"Unknown\",\n err instanceof Error ? err.message : String(err),\n ),\n });\n\nexport const fromAws = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const awsErr = err as {\n name?: unknown;\n message?: unknown;\n $metadata?: { httpStatusCode?: unknown };\n };\n const name = typeof awsErr.name === \"string\" ? awsErr.name : undefined;\n const message =\n typeof awsErr.message === \"string\" ? awsErr.message : `AWS error: ${name ?? \"unknown\"}`;\n const status =\n typeof awsErr.$metadata?.httpStatusCode === \"number\"\n ? awsErr.$metadata.httpStatusCode\n : undefined;\n\n const cause = toCause(\n name ?? (status !== undefined ? String(status) : \"Unknown\"),\n message,\n status !== undefined ? { httpStatusCode: status } : undefined,\n );\n\n // 1) name-based mapping wins (more specific than HTTP status)\n if (name && name in AWS_NAME_TO_CODE) {\n const m = AWS_NAME_TO_CODE[name]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 2) HTTP status mapping\n if (status !== undefined && status in HTTP_STATUS_TO_CODE) {\n const m = HTTP_STATUS_TO_CODE[status]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 3) 5xx bucket\n if (status !== undefined && status >= 500 && status < 600) {\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n }\n\n // 4) anything else 4xx-shaped\n if (status !== undefined && status >= 400 && status < 500) {\n return new FileSystemError({ code: \"Forbidden\", message, retryable: false, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromPg = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const pgErr = err as { code?: unknown; message?: unknown };\n const sqlstate = typeof pgErr.code === \"string\" ? pgErr.code : undefined;\n const message =\n typeof pgErr.message === \"string\" ? pgErr.message : `Postgres error: ${sqlstate ?? \"unknown\"}`;\n const cause = toCause(sqlstate ?? \"Unknown\", message);\n\n if (sqlstate && sqlstate in PG_SQLSTATE_TO_CODE) {\n const m = PG_SQLSTATE_TO_CODE[sqlstate]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromSqlite = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const sqlErr = err as { code?: unknown; message?: unknown };\n const code = typeof sqlErr.code === \"string\" ? sqlErr.code : undefined;\n const message =\n typeof sqlErr.message === \"string\" ? sqlErr.message : `SQLite error: ${code ?? \"unknown\"}`;\n const cause = toCause(code ?? \"Unknown\", message);\n\n if (code && code in SQLITE_CODE_TO_CODE) {\n const m = SQLITE_CODE_TO_CODE[code]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n","/**\n * FileSystemError — the single error class every adapter, store,\n * server action, and route handler in `file-next` returns or throws.\n *\n * Spec reference: requirement \"FileSystemError discriminated union\"\n * in `sdd/file-next/spec`. The 11 codes are the CLOSED set; any\n * provider-specific code (e.g. S3 `NoSuchKey`, Postgres `23505`) is\n * preserved on `cause.code` so callers can still distinguish upstream\n * reasons while the top-level `code` stays in the catalog.\n *\n * The catalog is a merge of spec + impl: the 6 fixed codes\n * (NotFound, Forbidden, Conflict, QuotaExceeded, NetworkError,\n * InternalError) are non-negotiable; the remaining 5 keep the wire\n * aligned with both the HTTP boundary (route handlers map the\n * top-level `code` to a status directly) and the storage boundary\n * (`RateLimited` and `ChecksumMismatch` carry semantics that have\n * no natural HTTP equivalent). See\n * `sdd/file-next/decisions/error-codes-deviation` for the\n * deviation log and rationale.\n *\n * Retryability table is the design's `error-mapping` excerpt; see\n * `sdd/file-next/design` §C. Any future code MUST add an entry in\n * `RETRYABLE_BY_CODE` (the catalog test enforces this).\n *\n * The placeholder from T-006 is replaced by this file in T-007a.\n * The upstream mappers (fromAws / fromPg / fromSqlite) land in T-007b\n * in `mappers.ts`.\n */\n\nexport const FILE_SYSTEM_ERROR_CODES = [\n \"NotFound\",\n \"Forbidden\",\n \"Conflict\",\n \"QuotaExceeded\",\n \"NetworkError\",\n \"InternalError\",\n \"Unauthorized\",\n \"PayloadTooLarge\",\n \"UnsupportedMediaType\",\n \"RateLimited\",\n \"ChecksumMismatch\",\n] as const satisfies readonly string[];\n\nexport type FileSystemErrorCode = (typeof FILE_SYSTEM_ERROR_CODES)[number];\n\nexport const RETRYABLE_BY_CODE: Readonly<Record<FileSystemErrorCode, boolean>> = {\n NotFound: false,\n Forbidden: false,\n Conflict: false,\n QuotaExceeded: true,\n NetworkError: true,\n InternalError: true,\n Unauthorized: false,\n PayloadTooLarge: false,\n UnsupportedMediaType: false,\n RateLimited: true,\n ChecksumMismatch: true,\n};\n\nexport interface FileSystemErrorOptions {\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport interface FileSystemErrorJson {\n name: string;\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport class FileSystemError extends Error {\n readonly code: FileSystemErrorCode;\n readonly retryable: boolean;\n override readonly cause?: { code: string; message: string; [k: string]: unknown };\n\n constructor(opts: FileSystemErrorOptions) {\n super(opts.message);\n this.name = \"FileSystemError\";\n this.code = opts.code;\n this.retryable = opts.retryable;\n if (opts.cause !== undefined) {\n this.cause = opts.cause;\n }\n }\n\n /**\n * Stable JSON shape for RSC pass-through. Error.prototype.message\n * is non-enumerable, so plain `JSON.stringify(err)` would emit `{}`\n * and lose the message + code + retryable flag. `cause` is omitted\n * entirely (not set to undefined) when absent so the shape stays\n * stable for hash-based caches.\n */\n toJSON(): FileSystemErrorJson {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n };\n }\n\n /**\n * Mappers from upstream error shapes (AWS SDK v3, node-postgres,\n * better-sqlite3) to FileSystemError. See `./mappers.ts` for the\n * mapping tables. Re-exposed as static methods so callers can pick\n * the import style that fits; the free functions are the canonical\n * implementation.\n */\n static fromAws(err: unknown): FileSystemError {\n // Lazy import via the runtime binding avoids the static-field\n // circular-dep trap in ESM. The mapper file imports this class\n // for instanceof checks; we look up the function at call time.\n return _fromAws(err);\n }\n\n static fromPg(err: unknown): FileSystemError {\n return _fromPg(err);\n }\n\n static fromSqlite(err: unknown): FileSystemError {\n return _fromSqlite(err);\n }\n}\n\n// Imported here as bindings (not values) so the static methods above\n// can resolve them lazily. The actual implementation lives in mappers.ts.\nimport { fromAws as _fromAws, fromPg as _fromPg, fromSqlite as _fromSqlite } from \"./mappers\";\nexport { fromAws, fromPg, fromSqlite } from \"./mappers\";\n","/**\n * Branded string types and their constructors/guards.\n *\n * Brands are TypeScript-only fictions: a `Path` and an `S3Key` are\n * both strings at runtime, but the type system treats them as\n * distinct nominal types so the compiler catches accidental\n * cross-assignment (e.g. passing an S3Key where a TenantId is\n * expected).\n *\n * Conventions:\n * - `as*` is a zero-cost cast: trust the caller, brand the value.\n * Use it at trust boundaries you have already validated.\n * - `assert*` is a runtime guard: throws TypeError on invalid\n * input. Use it at the edge (parsing user/env input).\n *\n * Validation rules are intentionally minimal in v0.1 and can be\n * tightened as the spec evolves. None of them touch the network or\n * allocate; they are safe in hot paths.\n */\n\nexport type Path = string & { readonly __brand: \"Path\" };\nexport type Prefix = string & { readonly __brand: \"Prefix\" };\nexport type S3Key = string & { readonly __brand: \"S3Key\" };\nexport type TenantId = string & { readonly __brand: \"TenantId\" };\nexport type UserId = string & { readonly __brand: \"UserId\" };\n\n/**\n * POSIX file path. Non-empty, '/' is allowed as the root.\n */\nexport const asPath = (s: string): Path => s as Path;\nexport const assertPath = (s: string): Path => {\n if (s.length === 0) {\n throw new TypeError(\"Path must be a non-empty string\");\n }\n return s as Path;\n};\n\n/**\n * S3 prefix. Empty string is the root prefix. Non-empty prefixes\n * MUST end with '/' so concatenation with a key never produces\n * 'usersfile.jpg' by accident.\n */\nexport const asPrefix = (s: string): Prefix => s as Prefix;\nexport const assertPrefix = (s: string): Prefix => {\n if (s.length > 0 && !s.endsWith(\"/\")) {\n throw new TypeError(\n `Prefix must end with \"/\" or be empty: ${JSON.stringify(s)}`,\n );\n }\n return s as Prefix;\n};\n\n/**\n * S3 object key. No leading slash, no empty segments, no '..' hops.\n */\nexport const asS3Key = (s: string): S3Key => s as S3Key;\nexport const assertS3Key = (s: string): S3Key => {\n if (s.length === 0) {\n throw new TypeError(\"S3Key must be a non-empty string\");\n }\n if (s.startsWith(\"/\")) {\n throw new TypeError(\n `S3Key must not start with a slash: ${JSON.stringify(s)}`,\n );\n }\n if (s.includes(\"..\")) {\n throw new TypeError(\n `S3Key must not contain '..' segments: ${JSON.stringify(s)}`,\n );\n }\n return s as S3Key;\n};\n\n/**\n * Tenant identifier. Alphanumerics, dashes, underscores only.\n */\nexport const asTenantId = (s: string): TenantId => s as TenantId;\nexport const assertTenantId = (s: string): TenantId => {\n if (s.length === 0 || !/^[a-zA-Z0-9_-]+$/.test(s)) {\n throw new TypeError(`Invalid TenantId: ${JSON.stringify(s)}`);\n }\n return s as TenantId;\n};\n\n/**\n * Opaque user identifier. Non-empty; the format is provider-defined.\n */\nexport const asUserId = (s: string): UserId => s as UserId;\nexport const assertUserId = (s: string): UserId => {\n if (s.length === 0) {\n throw new TypeError(\"UserId must be a non-empty string\");\n }\n return s as UserId;\n};\n","/**\n * WriteThrough — keeps object storage and the metadata tree in lockstep.\n *\n * Object keys are the node UUID. Rename/move stay metadata-only.\n * Copy writes a new object under a new UUID.\n */\nimport { ok, err, type Result } from \"@/types/result\";\nimport { FileSystemError } from \"@/errors\";\nimport { asS3Key, asTenantId, asUserId, type S3Key, type TenantId } from \"@/types/branded\";\nimport type { FileSystem } from \"../storage/filesystem\";\nimport type { MetadataStore, FileNode, CreateNodeInput } from \"../metadata/store\";\n\nexport type OrphanOp = \"delete\" | \"restore\";\n\nexport interface PendingOrphan {\n readonly id: string;\n readonly tenantId: TenantId;\n readonly s3Key: S3Key;\n readonly op: OrphanOp;\n readonly createdAt: Date;\n readonly reason: string;\n readonly nodeId?: string;\n}\n\nexport interface WriteThroughFileInput {\n readonly tenantId: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly body: Uint8Array | ReadableStream<Uint8Array>;\n readonly contentType: string;\n readonly metadata?: Readonly<Record<string, string>>;\n readonly ownerId?: string;\n readonly maxBytes?: number;\n readonly id?: string;\n}\n\nexport interface DeleteThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly recursive?: boolean;\n}\n\nexport interface CopyThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly newParentId: string | null;\n readonly newName?: string;\n}\n\nexport interface ConfirmUploadInput {\n readonly tenantId: string;\n readonly id: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly contentType?: string;\n readonly size?: number;\n readonly ownerId?: string;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface ReconcileReport {\n readonly orphans: ReadonlyArray<PendingOrphan>;\n readonly scanned: number;\n readonly missingInS3: ReadonlyArray<string>;\n readonly orphansInS3: ReadonlyArray<string>;\n readonly fixed: number;\n}\n\nconst bootedTenants = new Set<string>();\n\nexport const __resetDrainState = (): void => {\n bootedTenants.clear();\n};\n\nconst newId = (): string =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : `node-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n\nconst scopedFs = (fs: FileSystem, tenantId: string): FileSystem =>\n fs.tenantId === tenantId ? fs : fs.forTenant(tenantId);\n\nconst bodySize = (body: WriteThroughFileInput[\"body\"]): number => {\n const maybe = body as { byteLength?: number };\n return typeof maybe.byteLength === \"number\" ? maybe.byteLength : 0;\n};\n\nconst drainPendingOrphansFor = async (\n fs: FileSystem,\n store: MetadataStore,\n tenantId: TenantId,\n): Promise<void> => {\n if (bootedTenants.has(tenantId)) return;\n bootedTenants.add(tenantId);\n const result = await store.listPendingOrphans({ tenantId });\n if (!result.ok) return;\n const adapter = scopedFs(fs, tenantId).adapter;\n for (const orphan of result.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n await store.deleteOrphan({ tenantId, id: orphan.id });\n }\n};\n\nexport const createWriteThrough = (\n fs: FileSystem,\n store: MetadataStore,\n): {\n writeThroughFile: (\n input: WriteThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n deleteThroughFile: (\n input: DeleteThroughFileInput,\n ) => Promise<Result<void, FileSystemError>>;\n purgeThroughFile: (\n input: { tenantId: string; id: string },\n ) => Promise<Result<void, FileSystemError>>;\n copyThroughFile: (\n input: CopyThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n confirmUpload: (\n input: ConfirmUploadInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n reconcile: (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }) => Promise<Result<ReconcileReport, FileSystemError>>;\n getOrphans: () => ReadonlyArray<PendingOrphan>;\n} => {\n const writeThroughFile = async (\n input: WriteThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const id = input.id ?? newId();\n const s3Key = asS3Key(id);\n const calcSize = bodySize(input.body);\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + calcSize > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n const w = await adapter.write({\n key: s3Key,\n body: input.body,\n contentType: input.contentType,\n metadata: input.metadata,\n });\n if (!w.ok) return w;\n\n const ownerId = input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\");\n const createInput: CreateNodeInput = {\n id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size: calcSize,\n mimeType: input.contentType,\n s3Key,\n ownerId,\n metadata: input.metadata,\n };\n const c = await store.createNode(createInput);\n if (!c.ok) {\n const enqueue = await store.enqueueOrphan({\n tenantId,\n s3Key,\n reason: c.error.message,\n });\n if (!enqueue.ok) {\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded, metadata insert failed, and orphan enqueue failed: ${enqueue.error.message}; original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n await adapter.delete({ key: s3Key });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded but metadata insert failed; orphan logged for reconcile. S3 cleanup attempted. Original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n\n return ok(c.value);\n };\n\n const deleteThroughFile = async (\n input: DeleteThroughFileInput,\n ): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const node = g.value;\n const d = await store.deleteNode({\n tenantId,\n id: input.id,\n recursive: input.recursive,\n });\n if (!d.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key || node.id),\n metadataId: input.id,\n reason: d.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata soft-delete failed; orphan logged. Original: ${d.error.message}`,\n retryable: false,\n }),\n );\n }\n\n if (node.kind === \"file\" && node.s3Key) {\n const del = await adapter.delete({ key: asS3Key(node.s3Key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key),\n metadataId: input.id,\n reason: del.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata deleted but S3 delete failed; orphan logged. Original: ${del.error.message}`,\n retryable: false,\n }),\n );\n }\n }\n\n return ok(undefined);\n };\n\n const purgeThroughFile = async (input: {\n tenantId: string;\n id: string;\n }): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const purged = await store.purgeNode({ tenantId, id: input.id });\n if (!purged.ok) return purged;\n for (const key of purged.value.s3Keys) {\n const del = await adapter.delete({ key: asS3Key(key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(key),\n metadataId: input.id,\n reason: del.error.message,\n });\n }\n }\n return ok(undefined);\n };\n\n const copyThroughFile = async (\n input: CopyThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const src = g.value;\n const id = newId();\n if (src.kind === \"file\" && src.s3Key) {\n const copied = await adapter.copy({\n sourceKey: asS3Key(src.s3Key),\n destinationKey: asS3Key(id),\n });\n if (!copied.ok) return copied;\n }\n return store.createNode({\n id,\n tenantId,\n parentId: input.newParentId,\n name: input.newName ?? src.name,\n kind: src.kind,\n size: src.size,\n mimeType: src.mimeType,\n s3Key: src.kind === \"file\" ? id : \"\",\n ownerId: src.ownerId,\n metadata: src.metadata,\n });\n };\n\n const confirmUpload = async (\n input: ConfirmUploadInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const existing = await store.findByS3Key({ tenantId, s3Key: input.id });\n if (existing.ok && existing.value) return ok(existing.value);\n\n const st = await adapter.stat({ key: asS3Key(input.id) });\n const size = st.ok ? st.value.size : (input.size ?? 0);\n const mimeType = input.contentType ?? (st.ok ? st.value.contentType : \"\");\n if (!st.ok && input.size === undefined) return st;\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + size > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n return store.createNode({\n id: input.id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size,\n mimeType,\n s3Key: input.id,\n ownerId: input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\"),\n metadata: input.metadata,\n });\n };\n\n const reconcile = async (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }): Promise<Result<ReconcileReport, FileSystemError>> => {\n if (!input?.tenantId) {\n return ok({\n orphans: [],\n scanned: 0,\n missingInS3: [],\n orphansInS3: [],\n fixed: 0,\n });\n }\n const tenantId = asTenantId(input.tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const dryRun = input.dryRun === true;\n let fixed = 0;\n\n const pending = await store.listPendingOrphans({ tenantId });\n if (!pending.ok) return pending;\n if (!dryRun) {\n for (const orphan of pending.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n const del = await store.deleteOrphan({ tenantId, id: orphan.id });\n if (del.ok) fixed += 1;\n }\n }\n\n const keys = await store.scanFileKeys({ tenantId });\n if (!keys.ok) return keys;\n const missingInS3: string[] = [];\n for (const row of keys.value) {\n const exists = await adapter.exists({ key: asS3Key(row.s3Key) });\n if (exists.ok && !exists.value.exists) missingInS3.push(row.s3Key);\n }\n\n const listed = await adapter.list({ prefix: \"\" as never });\n const orphansInS3: string[] = [];\n if (listed.ok) {\n const known = new Set(keys.value.map((k) => k.s3Key));\n for (const item of listed.value.items) {\n if (!known.has(item.key)) orphansInS3.push(item.key);\n }\n }\n\n return ok({\n orphans: pending.value.map((orphan) => ({\n id: orphan.id,\n tenantId: orphan.tenantId,\n s3Key: orphan.s3Key,\n op: \"delete\" as const,\n createdAt: orphan.createdAt,\n reason: orphan.reason,\n nodeId: orphan.metadataId ?? undefined,\n })),\n scanned: keys.value.length,\n missingInS3,\n orphansInS3,\n fixed,\n });\n };\n\n return {\n writeThroughFile,\n deleteThroughFile,\n purgeThroughFile,\n copyThroughFile,\n confirmUpload,\n reconcile,\n getOrphans: () => [],\n };\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { a as FileSystem, M as MetadataStore, R as Result, F as FileNode, T as TenantId, c as S3Key } from '../filesystem-BbZJLy4A.cjs';
1
+ import { a as FileSystem, M as MetadataStore, R as Result, F as FileNode, T as TenantId, c as S3Key } from '../filesystem-CewcaWEl.cjs';
2
2
  import { FileSystemError } from '../errors/index.cjs';
3
3
  import 'zod';
4
4
 
@@ -61,6 +61,10 @@ interface ReconcileReport {
61
61
  declare const createWriteThrough: (fs: FileSystem, store: MetadataStore) => {
62
62
  writeThroughFile: (input: WriteThroughFileInput) => Promise<Result<FileNode, FileSystemError>>;
63
63
  deleteThroughFile: (input: DeleteThroughFileInput) => Promise<Result<void, FileSystemError>>;
64
+ purgeThroughFile: (input: {
65
+ tenantId: string;
66
+ id: string;
67
+ }) => Promise<Result<void, FileSystemError>>;
64
68
  copyThroughFile: (input: CopyThroughFileInput) => Promise<Result<FileNode, FileSystemError>>;
65
69
  confirmUpload: (input: ConfirmUploadInput) => Promise<Result<FileNode, FileSystemError>>;
66
70
  reconcile: (input?: {
@@ -1,4 +1,4 @@
1
- import { a as FileSystem, M as MetadataStore, R as Result, F as FileNode, T as TenantId, c as S3Key } from '../filesystem-D1Jjx3md.js';
1
+ import { a as FileSystem, M as MetadataStore, R as Result, F as FileNode, T as TenantId, c as S3Key } from '../filesystem-B0bJh8bW.js';
2
2
  import { FileSystemError } from '../errors/index.js';
3
3
  import 'zod';
4
4
 
@@ -61,6 +61,10 @@ interface ReconcileReport {
61
61
  declare const createWriteThrough: (fs: FileSystem, store: MetadataStore) => {
62
62
  writeThroughFile: (input: WriteThroughFileInput) => Promise<Result<FileNode, FileSystemError>>;
63
63
  deleteThroughFile: (input: DeleteThroughFileInput) => Promise<Result<void, FileSystemError>>;
64
+ purgeThroughFile: (input: {
65
+ tenantId: string;
66
+ id: string;
67
+ }) => Promise<Result<void, FileSystemError>>;
64
68
  copyThroughFile: (input: CopyThroughFileInput) => Promise<Result<FileNode, FileSystemError>>;
65
69
  confirmUpload: (input: ConfirmUploadInput) => Promise<Result<FileNode, FileSystemError>>;
66
70
  reconcile: (input?: {
@@ -297,6 +297,25 @@ var createWriteThrough = (fs, store) => {
297
297
  }
298
298
  return ok(void 0);
299
299
  };
300
+ const purgeThroughFile = async (input) => {
301
+ const tenantId = asTenantId(input.tenantId);
302
+ await drainPendingOrphansFor(fs, store, tenantId);
303
+ const adapter = scopedFs(fs, tenantId).adapter;
304
+ const purged = await store.purgeNode({ tenantId, id: input.id });
305
+ if (!purged.ok) return purged;
306
+ for (const key of purged.value.s3Keys) {
307
+ const del = await adapter.delete({ key: asS3Key(key) });
308
+ if (!del.ok) {
309
+ await store.enqueueOrphan({
310
+ tenantId,
311
+ s3Key: asS3Key(key),
312
+ metadataId: input.id,
313
+ reason: del.error.message
314
+ });
315
+ }
316
+ }
317
+ return ok(void 0);
318
+ };
300
319
  const copyThroughFile = async (input) => {
301
320
  const tenantId = asTenantId(input.tenantId);
302
321
  await drainPendingOrphansFor(fs, store, tenantId);
@@ -427,6 +446,7 @@ var createWriteThrough = (fs, store) => {
427
446
  return {
428
447
  writeThroughFile,
429
448
  deleteThroughFile,
449
+ purgeThroughFile,
430
450
  copyThroughFile,
431
451
  confirmUpload,
432
452
  reconcile,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/result.ts","../../src/errors/mappers.ts","../../src/errors/index.ts","../../src/types/branded.ts","../../src/sync/write-through.ts"],"names":["err"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Discriminated `Result<T, E>` for typed error returns.\n *\n * Why Result over throw at boundaries:\n * - No `any` at the call site (vs try/catch which loses the type).\n * - `switch (r.ok)` narrows the type in consumer code.\n * - The wire shape `{ ok, value | error }` is JSON-serializable,\n * so it survives the RSC boundary without an extra DTO.\n * - Helpers (`map`, `andThen`, `unwrap`) make the common shapes\n * (chain, bail-out, recover) terse and exhaustive.\n *\n * The default error type is `FileSystemError` (see `@/errors`).\n * Consumers can specialize: `Result<User, ZodError>`.\n *\n * All helpers are pure functions; they do NOT allocate closures in\n * hot paths beyond what the spec demands (no `try`/`catch` wrapping).\n */\n\nimport { FileSystemError } from \"@/errors\";\n\nexport type Result<T, E = FileSystemError> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\nexport const map = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => U,\n): Result<U, E> => (r.ok ? ok(f(r.value)) : r);\n\nexport const mapErr = <T, E, F>(\n r: Result<T, E>,\n f: (e: E) => F,\n): Result<T, F> => (r.ok ? r : err(f(r.error)));\n\nexport const andThen = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => Result<U, E>,\n): Result<U, E> => (r.ok ? f(r.value) : r);\n\nexport const unwrap = <T, E>(r: Result<T, E>): T => {\n if (r.ok) return r.value;\n throw r.error;\n};\n\nexport const unwrapOr = <T, E>(r: Result<T, E>, fallback: T): T =>\n r.ok ? r.value : fallback;\n","/**\n * Upstream error mappers for FileSystemError.\n *\n * Each mapper is a pure function `(*unknown) -> FileSystemError`.\n * The class re-exposes them as static methods (FileSystemError.fromAws\n * etc.) so callers can pick the import style that fits.\n *\n * Mapping strategy:\n * 1. If the input is already a FileSystemError, return it as-is\n * (we never re-wrap our own errors).\n * 2. Try the most specific signal first: S3 `name`, Postgres\n * SQLSTATE, SQLite extended code.\n * 3. Fall back to the HTTP status code (AWS SDK v3 exposes\n * `$metadata.httpStatusCode`).\n * 4. Last resort: InternalError, retryable, with the original\n * payload in `cause`.\n *\n * Provider-specific codes are preserved on `cause.code` (e.g. S3\n * \"NoSuchKey\", Postgres \"23505\") so callers can still branch on\n * them while the top-level `code` stays in the 11-code spec catalog.\n *\n * Mapping notes (post-C' merge, see\n * `sdd/file-next/decisions/error-codes-deviation`):\n * - S3 `SlowDown` -> QuotaExceeded (broader than RateLimited;\n * SlowDown means reduce request rate, which\n * is conceptually quota pressure, not\n * throttling of a single call).\n * - S3 `BadDigest` -> ChecksumMismatch (checksum verified by\n * S3 on upload did not match the client).\n * - HTTP 429 -> RateLimited (was QuotaExceeded in the\n * pre-C' catalog; RateLimited is the more\n * specific code for throttling responses).\n * - HTTP 408 -> NetworkError (transient transport error).\n * - HTTP 400 / Postgres 23514 / S3 InvalidRequest\n * -> fall through to the 4xx branch (no\n * top-level 400 code in the C' catalog;\n * these inputs are usually caught by the\n * name/SQLSTATE mapping first anyway).\n */\n\nimport { FileSystemError, type FileSystemErrorCode } from \"./index\";\n\n/* ---------------------------------------------------------------- *\n * Mapping tables (private) *\n * ---------------------------------------------------------------- */\n\ninterface CodeMapping {\n code: FileSystemErrorCode;\n retryable: boolean;\n}\n\nconst HTTP_STATUS_TO_CODE: Readonly<Record<number, CodeMapping>> = {\n 401: { code: \"Unauthorized\", retryable: false },\n 403: { code: \"Forbidden\", retryable: false },\n 404: { code: \"NotFound\", retryable: false },\n 408: { code: \"NetworkError\", retryable: true },\n 409: { code: \"Conflict\", retryable: false },\n 413: { code: \"PayloadTooLarge\", retryable: false },\n 415: { code: \"UnsupportedMediaType\", retryable: false },\n 429: { code: \"RateLimited\", retryable: true },\n};\n\nconst AWS_NAME_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n NoSuchKey: { code: \"NotFound\", retryable: false },\n NoSuchBucket: { code: \"NotFound\", retryable: false },\n // v0.2 multipart: unknown/aborted/expired uploadId.\n NoSuchUpload: { code: \"NotFound\", retryable: false },\n AccessDenied: { code: \"Forbidden\", retryable: false },\n SlowDown: { code: \"QuotaExceeded\", retryable: true },\n BadDigest: { code: \"ChecksumMismatch\", retryable: true },\n XAmzContentSHA256Mismatch: { code: \"ChecksumMismatch\", retryable: true },\n NetworkingError: { code: \"NetworkError\", retryable: true },\n TimeoutError: { code: \"NetworkError\", retryable: true },\n};\n\nconst PG_SQLSTATE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n \"23505\": { code: \"Conflict\", retryable: false },\n};\n\nconst SQLITE_CODE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n SQLITE_CONSTRAINT_UNIQUE: { code: \"Conflict\", retryable: false },\n SQLITE_CONSTRAINT_PRIMARYKEY: { code: \"Conflict\", retryable: false },\n};\n\n/* ---------------------------------------------------------------- *\n * Public mappers *\n * ---------------------------------------------------------------- */\n\nconst toCause = (code: string, message: string, extra?: Record<string, unknown>) => ({\n code,\n message,\n ...(extra ?? {}),\n});\n\nconst fallback = (err: unknown): FileSystemError =>\n new FileSystemError({\n code: \"InternalError\",\n message: err instanceof Error ? err.message : String(err),\n retryable: true,\n cause: toCause(\n \"Unknown\",\n err instanceof Error ? err.message : String(err),\n ),\n });\n\nexport const fromAws = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const awsErr = err as {\n name?: unknown;\n message?: unknown;\n $metadata?: { httpStatusCode?: unknown };\n };\n const name = typeof awsErr.name === \"string\" ? awsErr.name : undefined;\n const message =\n typeof awsErr.message === \"string\" ? awsErr.message : `AWS error: ${name ?? \"unknown\"}`;\n const status =\n typeof awsErr.$metadata?.httpStatusCode === \"number\"\n ? awsErr.$metadata.httpStatusCode\n : undefined;\n\n const cause = toCause(\n name ?? (status !== undefined ? String(status) : \"Unknown\"),\n message,\n status !== undefined ? { httpStatusCode: status } : undefined,\n );\n\n // 1) name-based mapping wins (more specific than HTTP status)\n if (name && name in AWS_NAME_TO_CODE) {\n const m = AWS_NAME_TO_CODE[name]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 2) HTTP status mapping\n if (status !== undefined && status in HTTP_STATUS_TO_CODE) {\n const m = HTTP_STATUS_TO_CODE[status]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 3) 5xx bucket\n if (status !== undefined && status >= 500 && status < 600) {\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n }\n\n // 4) anything else 4xx-shaped\n if (status !== undefined && status >= 400 && status < 500) {\n return new FileSystemError({ code: \"Forbidden\", message, retryable: false, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromPg = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const pgErr = err as { code?: unknown; message?: unknown };\n const sqlstate = typeof pgErr.code === \"string\" ? pgErr.code : undefined;\n const message =\n typeof pgErr.message === \"string\" ? pgErr.message : `Postgres error: ${sqlstate ?? \"unknown\"}`;\n const cause = toCause(sqlstate ?? \"Unknown\", message);\n\n if (sqlstate && sqlstate in PG_SQLSTATE_TO_CODE) {\n const m = PG_SQLSTATE_TO_CODE[sqlstate]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromSqlite = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const sqlErr = err as { code?: unknown; message?: unknown };\n const code = typeof sqlErr.code === \"string\" ? sqlErr.code : undefined;\n const message =\n typeof sqlErr.message === \"string\" ? sqlErr.message : `SQLite error: ${code ?? \"unknown\"}`;\n const cause = toCause(code ?? \"Unknown\", message);\n\n if (code && code in SQLITE_CODE_TO_CODE) {\n const m = SQLITE_CODE_TO_CODE[code]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n","/**\n * FileSystemError — the single error class every adapter, store,\n * server action, and route handler in `file-next` returns or throws.\n *\n * Spec reference: requirement \"FileSystemError discriminated union\"\n * in `sdd/file-next/spec`. The 11 codes are the CLOSED set; any\n * provider-specific code (e.g. S3 `NoSuchKey`, Postgres `23505`) is\n * preserved on `cause.code` so callers can still distinguish upstream\n * reasons while the top-level `code` stays in the catalog.\n *\n * The catalog is a merge of spec + impl: the 6 fixed codes\n * (NotFound, Forbidden, Conflict, QuotaExceeded, NetworkError,\n * InternalError) are non-negotiable; the remaining 5 keep the wire\n * aligned with both the HTTP boundary (route handlers map the\n * top-level `code` to a status directly) and the storage boundary\n * (`RateLimited` and `ChecksumMismatch` carry semantics that have\n * no natural HTTP equivalent). See\n * `sdd/file-next/decisions/error-codes-deviation` for the\n * deviation log and rationale.\n *\n * Retryability table is the design's `error-mapping` excerpt; see\n * `sdd/file-next/design` §C. Any future code MUST add an entry in\n * `RETRYABLE_BY_CODE` (the catalog test enforces this).\n *\n * The placeholder from T-006 is replaced by this file in T-007a.\n * The upstream mappers (fromAws / fromPg / fromSqlite) land in T-007b\n * in `mappers.ts`.\n */\n\nexport const FILE_SYSTEM_ERROR_CODES = [\n \"NotFound\",\n \"Forbidden\",\n \"Conflict\",\n \"QuotaExceeded\",\n \"NetworkError\",\n \"InternalError\",\n \"Unauthorized\",\n \"PayloadTooLarge\",\n \"UnsupportedMediaType\",\n \"RateLimited\",\n \"ChecksumMismatch\",\n] as const satisfies readonly string[];\n\nexport type FileSystemErrorCode = (typeof FILE_SYSTEM_ERROR_CODES)[number];\n\nexport const RETRYABLE_BY_CODE: Readonly<Record<FileSystemErrorCode, boolean>> = {\n NotFound: false,\n Forbidden: false,\n Conflict: false,\n QuotaExceeded: true,\n NetworkError: true,\n InternalError: true,\n Unauthorized: false,\n PayloadTooLarge: false,\n UnsupportedMediaType: false,\n RateLimited: true,\n ChecksumMismatch: true,\n};\n\nexport interface FileSystemErrorOptions {\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport interface FileSystemErrorJson {\n name: string;\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport class FileSystemError extends Error {\n readonly code: FileSystemErrorCode;\n readonly retryable: boolean;\n override readonly cause?: { code: string; message: string; [k: string]: unknown };\n\n constructor(opts: FileSystemErrorOptions) {\n super(opts.message);\n this.name = \"FileSystemError\";\n this.code = opts.code;\n this.retryable = opts.retryable;\n if (opts.cause !== undefined) {\n this.cause = opts.cause;\n }\n }\n\n /**\n * Stable JSON shape for RSC pass-through. Error.prototype.message\n * is non-enumerable, so plain `JSON.stringify(err)` would emit `{}`\n * and lose the message + code + retryable flag. `cause` is omitted\n * entirely (not set to undefined) when absent so the shape stays\n * stable for hash-based caches.\n */\n toJSON(): FileSystemErrorJson {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n };\n }\n\n /**\n * Mappers from upstream error shapes (AWS SDK v3, node-postgres,\n * better-sqlite3) to FileSystemError. See `./mappers.ts` for the\n * mapping tables. Re-exposed as static methods so callers can pick\n * the import style that fits; the free functions are the canonical\n * implementation.\n */\n static fromAws(err: unknown): FileSystemError {\n // Lazy import via the runtime binding avoids the static-field\n // circular-dep trap in ESM. The mapper file imports this class\n // for instanceof checks; we look up the function at call time.\n return _fromAws(err);\n }\n\n static fromPg(err: unknown): FileSystemError {\n return _fromPg(err);\n }\n\n static fromSqlite(err: unknown): FileSystemError {\n return _fromSqlite(err);\n }\n}\n\n// Imported here as bindings (not values) so the static methods above\n// can resolve them lazily. The actual implementation lives in mappers.ts.\nimport { fromAws as _fromAws, fromPg as _fromPg, fromSqlite as _fromSqlite } from \"./mappers\";\nexport { fromAws, fromPg, fromSqlite } from \"./mappers\";\n","/**\n * Branded string types and their constructors/guards.\n *\n * Brands are TypeScript-only fictions: a `Path` and an `S3Key` are\n * both strings at runtime, but the type system treats them as\n * distinct nominal types so the compiler catches accidental\n * cross-assignment (e.g. passing an S3Key where a TenantId is\n * expected).\n *\n * Conventions:\n * - `as*` is a zero-cost cast: trust the caller, brand the value.\n * Use it at trust boundaries you have already validated.\n * - `assert*` is a runtime guard: throws TypeError on invalid\n * input. Use it at the edge (parsing user/env input).\n *\n * Validation rules are intentionally minimal in v0.1 and can be\n * tightened as the spec evolves. None of them touch the network or\n * allocate; they are safe in hot paths.\n */\n\nexport type Path = string & { readonly __brand: \"Path\" };\nexport type Prefix = string & { readonly __brand: \"Prefix\" };\nexport type S3Key = string & { readonly __brand: \"S3Key\" };\nexport type TenantId = string & { readonly __brand: \"TenantId\" };\nexport type UserId = string & { readonly __brand: \"UserId\" };\n\n/**\n * POSIX file path. Non-empty, '/' is allowed as the root.\n */\nexport const asPath = (s: string): Path => s as Path;\nexport const assertPath = (s: string): Path => {\n if (s.length === 0) {\n throw new TypeError(\"Path must be a non-empty string\");\n }\n return s as Path;\n};\n\n/**\n * S3 prefix. Empty string is the root prefix. Non-empty prefixes\n * MUST end with '/' so concatenation with a key never produces\n * 'usersfile.jpg' by accident.\n */\nexport const asPrefix = (s: string): Prefix => s as Prefix;\nexport const assertPrefix = (s: string): Prefix => {\n if (s.length > 0 && !s.endsWith(\"/\")) {\n throw new TypeError(\n `Prefix must end with \"/\" or be empty: ${JSON.stringify(s)}`,\n );\n }\n return s as Prefix;\n};\n\n/**\n * S3 object key. No leading slash, no empty segments, no '..' hops.\n */\nexport const asS3Key = (s: string): S3Key => s as S3Key;\nexport const assertS3Key = (s: string): S3Key => {\n if (s.length === 0) {\n throw new TypeError(\"S3Key must be a non-empty string\");\n }\n if (s.startsWith(\"/\")) {\n throw new TypeError(\n `S3Key must not start with a slash: ${JSON.stringify(s)}`,\n );\n }\n if (s.includes(\"..\")) {\n throw new TypeError(\n `S3Key must not contain '..' segments: ${JSON.stringify(s)}`,\n );\n }\n return s as S3Key;\n};\n\n/**\n * Tenant identifier. Alphanumerics, dashes, underscores only.\n */\nexport const asTenantId = (s: string): TenantId => s as TenantId;\nexport const assertTenantId = (s: string): TenantId => {\n if (s.length === 0 || !/^[a-zA-Z0-9_-]+$/.test(s)) {\n throw new TypeError(`Invalid TenantId: ${JSON.stringify(s)}`);\n }\n return s as TenantId;\n};\n\n/**\n * Opaque user identifier. Non-empty; the format is provider-defined.\n */\nexport const asUserId = (s: string): UserId => s as UserId;\nexport const assertUserId = (s: string): UserId => {\n if (s.length === 0) {\n throw new TypeError(\"UserId must be a non-empty string\");\n }\n return s as UserId;\n};\n","/**\n * WriteThrough — keeps object storage and the metadata tree in lockstep.\n *\n * Object keys are the node UUID. Rename/move stay metadata-only.\n * Copy writes a new object under a new UUID.\n */\nimport { ok, err, type Result } from \"@/types/result\";\nimport { FileSystemError } from \"@/errors\";\nimport { asS3Key, asTenantId, asUserId, type S3Key, type TenantId } from \"@/types/branded\";\nimport type { FileSystem } from \"../storage/filesystem\";\nimport type { MetadataStore, FileNode, CreateNodeInput } from \"../metadata/store\";\n\nexport type OrphanOp = \"delete\" | \"restore\";\n\nexport interface PendingOrphan {\n readonly id: string;\n readonly tenantId: TenantId;\n readonly s3Key: S3Key;\n readonly op: OrphanOp;\n readonly createdAt: Date;\n readonly reason: string;\n readonly nodeId?: string;\n}\n\nexport interface WriteThroughFileInput {\n readonly tenantId: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly body: Uint8Array | ReadableStream<Uint8Array>;\n readonly contentType: string;\n readonly metadata?: Readonly<Record<string, string>>;\n readonly ownerId?: string;\n readonly maxBytes?: number;\n readonly id?: string;\n}\n\nexport interface DeleteThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly recursive?: boolean;\n}\n\nexport interface CopyThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly newParentId: string | null;\n readonly newName?: string;\n}\n\nexport interface ConfirmUploadInput {\n readonly tenantId: string;\n readonly id: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly contentType?: string;\n readonly size?: number;\n readonly ownerId?: string;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface ReconcileReport {\n readonly orphans: ReadonlyArray<PendingOrphan>;\n readonly scanned: number;\n readonly missingInS3: ReadonlyArray<string>;\n readonly orphansInS3: ReadonlyArray<string>;\n readonly fixed: number;\n}\n\nconst bootedTenants = new Set<string>();\n\nexport const __resetDrainState = (): void => {\n bootedTenants.clear();\n};\n\nconst newId = (): string =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : `node-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n\nconst scopedFs = (fs: FileSystem, tenantId: string): FileSystem =>\n fs.tenantId === tenantId ? fs : fs.forTenant(tenantId);\n\nconst bodySize = (body: WriteThroughFileInput[\"body\"]): number => {\n const maybe = body as { byteLength?: number };\n return typeof maybe.byteLength === \"number\" ? maybe.byteLength : 0;\n};\n\nconst drainPendingOrphansFor = async (\n fs: FileSystem,\n store: MetadataStore,\n tenantId: TenantId,\n): Promise<void> => {\n if (bootedTenants.has(tenantId)) return;\n bootedTenants.add(tenantId);\n const result = await store.listPendingOrphans({ tenantId });\n if (!result.ok) return;\n const adapter = scopedFs(fs, tenantId).adapter;\n for (const orphan of result.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n await store.deleteOrphan({ tenantId, id: orphan.id });\n }\n};\n\nexport const createWriteThrough = (\n fs: FileSystem,\n store: MetadataStore,\n): {\n writeThroughFile: (\n input: WriteThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n deleteThroughFile: (\n input: DeleteThroughFileInput,\n ) => Promise<Result<void, FileSystemError>>;\n copyThroughFile: (\n input: CopyThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n confirmUpload: (\n input: ConfirmUploadInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n reconcile: (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }) => Promise<Result<ReconcileReport, FileSystemError>>;\n getOrphans: () => ReadonlyArray<PendingOrphan>;\n} => {\n const writeThroughFile = async (\n input: WriteThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const id = input.id ?? newId();\n const s3Key = asS3Key(id);\n const calcSize = bodySize(input.body);\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + calcSize > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n const w = await adapter.write({\n key: s3Key,\n body: input.body,\n contentType: input.contentType,\n metadata: input.metadata,\n });\n if (!w.ok) return w;\n\n const ownerId = input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\");\n const createInput: CreateNodeInput = {\n id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size: calcSize,\n mimeType: input.contentType,\n s3Key,\n ownerId,\n metadata: input.metadata,\n };\n const c = await store.createNode(createInput);\n if (!c.ok) {\n const enqueue = await store.enqueueOrphan({\n tenantId,\n s3Key,\n reason: c.error.message,\n });\n if (!enqueue.ok) {\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded, metadata insert failed, and orphan enqueue failed: ${enqueue.error.message}; original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n await adapter.delete({ key: s3Key });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded but metadata insert failed; orphan logged for reconcile. S3 cleanup attempted. Original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n\n return ok(c.value);\n };\n\n const deleteThroughFile = async (\n input: DeleteThroughFileInput,\n ): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const node = g.value;\n const d = await store.deleteNode({\n tenantId,\n id: input.id,\n recursive: input.recursive,\n });\n if (!d.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key || node.id),\n metadataId: input.id,\n reason: d.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata soft-delete failed; orphan logged. Original: ${d.error.message}`,\n retryable: false,\n }),\n );\n }\n\n if (node.kind === \"file\" && node.s3Key) {\n const del = await adapter.delete({ key: asS3Key(node.s3Key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key),\n metadataId: input.id,\n reason: del.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata deleted but S3 delete failed; orphan logged. Original: ${del.error.message}`,\n retryable: false,\n }),\n );\n }\n }\n\n return ok(undefined);\n };\n\n const copyThroughFile = async (\n input: CopyThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const src = g.value;\n const id = newId();\n if (src.kind === \"file\" && src.s3Key) {\n const copied = await adapter.copy({\n sourceKey: asS3Key(src.s3Key),\n destinationKey: asS3Key(id),\n });\n if (!copied.ok) return copied;\n }\n return store.createNode({\n id,\n tenantId,\n parentId: input.newParentId,\n name: input.newName ?? src.name,\n kind: src.kind,\n size: src.size,\n mimeType: src.mimeType,\n s3Key: src.kind === \"file\" ? id : \"\",\n ownerId: src.ownerId,\n metadata: src.metadata,\n });\n };\n\n const confirmUpload = async (\n input: ConfirmUploadInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const existing = await store.findByS3Key({ tenantId, s3Key: input.id });\n if (existing.ok && existing.value) return ok(existing.value);\n\n const st = await adapter.stat({ key: asS3Key(input.id) });\n const size = st.ok ? st.value.size : (input.size ?? 0);\n const mimeType = input.contentType ?? (st.ok ? st.value.contentType : \"\");\n if (!st.ok && input.size === undefined) return st;\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + size > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n return store.createNode({\n id: input.id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size,\n mimeType,\n s3Key: input.id,\n ownerId: input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\"),\n metadata: input.metadata,\n });\n };\n\n const reconcile = async (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }): Promise<Result<ReconcileReport, FileSystemError>> => {\n if (!input?.tenantId) {\n return ok({\n orphans: [],\n scanned: 0,\n missingInS3: [],\n orphansInS3: [],\n fixed: 0,\n });\n }\n const tenantId = asTenantId(input.tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const dryRun = input.dryRun === true;\n let fixed = 0;\n\n const pending = await store.listPendingOrphans({ tenantId });\n if (!pending.ok) return pending;\n if (!dryRun) {\n for (const orphan of pending.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n const del = await store.deleteOrphan({ tenantId, id: orphan.id });\n if (del.ok) fixed += 1;\n }\n }\n\n const keys = await store.scanFileKeys({ tenantId });\n if (!keys.ok) return keys;\n const missingInS3: string[] = [];\n for (const row of keys.value) {\n const exists = await adapter.exists({ key: asS3Key(row.s3Key) });\n if (exists.ok && !exists.value.exists) missingInS3.push(row.s3Key);\n }\n\n const listed = await adapter.list({ prefix: \"\" as never });\n const orphansInS3: string[] = [];\n if (listed.ok) {\n const known = new Set(keys.value.map((k) => k.s3Key));\n for (const item of listed.value.items) {\n if (!known.has(item.key)) orphansInS3.push(item.key);\n }\n }\n\n return ok({\n orphans: pending.value.map((orphan) => ({\n id: orphan.id,\n tenantId: orphan.tenantId,\n s3Key: orphan.s3Key,\n op: \"delete\" as const,\n createdAt: orphan.createdAt,\n reason: orphan.reason,\n nodeId: orphan.metadataId ?? undefined,\n })),\n scanned: keys.value.length,\n missingInS3,\n orphansInS3,\n fixed,\n });\n };\n\n return {\n writeThroughFile,\n deleteThroughFile,\n copyThroughFile,\n confirmUpload,\n reconcile,\n getOrphans: () => [],\n };\n};\n"]}
1
+ {"version":3,"sources":["../../src/types/result.ts","../../src/errors/mappers.ts","../../src/errors/index.ts","../../src/types/branded.ts","../../src/sync/write-through.ts"],"names":["err"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Discriminated `Result<T, E>` for typed error returns.\n *\n * Why Result over throw at boundaries:\n * - No `any` at the call site (vs try/catch which loses the type).\n * - `switch (r.ok)` narrows the type in consumer code.\n * - The wire shape `{ ok, value | error }` is JSON-serializable,\n * so it survives the RSC boundary without an extra DTO.\n * - Helpers (`map`, `andThen`, `unwrap`) make the common shapes\n * (chain, bail-out, recover) terse and exhaustive.\n *\n * The default error type is `FileSystemError` (see `@/errors`).\n * Consumers can specialize: `Result<User, ZodError>`.\n *\n * All helpers are pure functions; they do NOT allocate closures in\n * hot paths beyond what the spec demands (no `try`/`catch` wrapping).\n */\n\nimport { FileSystemError } from \"@/errors\";\n\nexport type Result<T, E = FileSystemError> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\nexport const err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\nexport const map = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => U,\n): Result<U, E> => (r.ok ? ok(f(r.value)) : r);\n\nexport const mapErr = <T, E, F>(\n r: Result<T, E>,\n f: (e: E) => F,\n): Result<T, F> => (r.ok ? r : err(f(r.error)));\n\nexport const andThen = <T, U, E>(\n r: Result<T, E>,\n f: (t: T) => Result<U, E>,\n): Result<U, E> => (r.ok ? f(r.value) : r);\n\nexport const unwrap = <T, E>(r: Result<T, E>): T => {\n if (r.ok) return r.value;\n throw r.error;\n};\n\nexport const unwrapOr = <T, E>(r: Result<T, E>, fallback: T): T =>\n r.ok ? r.value : fallback;\n","/**\n * Upstream error mappers for FileSystemError.\n *\n * Each mapper is a pure function `(*unknown) -> FileSystemError`.\n * The class re-exposes them as static methods (FileSystemError.fromAws\n * etc.) so callers can pick the import style that fits.\n *\n * Mapping strategy:\n * 1. If the input is already a FileSystemError, return it as-is\n * (we never re-wrap our own errors).\n * 2. Try the most specific signal first: S3 `name`, Postgres\n * SQLSTATE, SQLite extended code.\n * 3. Fall back to the HTTP status code (AWS SDK v3 exposes\n * `$metadata.httpStatusCode`).\n * 4. Last resort: InternalError, retryable, with the original\n * payload in `cause`.\n *\n * Provider-specific codes are preserved on `cause.code` (e.g. S3\n * \"NoSuchKey\", Postgres \"23505\") so callers can still branch on\n * them while the top-level `code` stays in the 11-code spec catalog.\n *\n * Mapping notes (post-C' merge, see\n * `sdd/file-next/decisions/error-codes-deviation`):\n * - S3 `SlowDown` -> QuotaExceeded (broader than RateLimited;\n * SlowDown means reduce request rate, which\n * is conceptually quota pressure, not\n * throttling of a single call).\n * - S3 `BadDigest` -> ChecksumMismatch (checksum verified by\n * S3 on upload did not match the client).\n * - HTTP 429 -> RateLimited (was QuotaExceeded in the\n * pre-C' catalog; RateLimited is the more\n * specific code for throttling responses).\n * - HTTP 408 -> NetworkError (transient transport error).\n * - HTTP 400 / Postgres 23514 / S3 InvalidRequest\n * -> fall through to the 4xx branch (no\n * top-level 400 code in the C' catalog;\n * these inputs are usually caught by the\n * name/SQLSTATE mapping first anyway).\n */\n\nimport { FileSystemError, type FileSystemErrorCode } from \"./index\";\n\n/* ---------------------------------------------------------------- *\n * Mapping tables (private) *\n * ---------------------------------------------------------------- */\n\ninterface CodeMapping {\n code: FileSystemErrorCode;\n retryable: boolean;\n}\n\nconst HTTP_STATUS_TO_CODE: Readonly<Record<number, CodeMapping>> = {\n 401: { code: \"Unauthorized\", retryable: false },\n 403: { code: \"Forbidden\", retryable: false },\n 404: { code: \"NotFound\", retryable: false },\n 408: { code: \"NetworkError\", retryable: true },\n 409: { code: \"Conflict\", retryable: false },\n 413: { code: \"PayloadTooLarge\", retryable: false },\n 415: { code: \"UnsupportedMediaType\", retryable: false },\n 429: { code: \"RateLimited\", retryable: true },\n};\n\nconst AWS_NAME_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n NoSuchKey: { code: \"NotFound\", retryable: false },\n NoSuchBucket: { code: \"NotFound\", retryable: false },\n // v0.2 multipart: unknown/aborted/expired uploadId.\n NoSuchUpload: { code: \"NotFound\", retryable: false },\n AccessDenied: { code: \"Forbidden\", retryable: false },\n SlowDown: { code: \"QuotaExceeded\", retryable: true },\n BadDigest: { code: \"ChecksumMismatch\", retryable: true },\n XAmzContentSHA256Mismatch: { code: \"ChecksumMismatch\", retryable: true },\n NetworkingError: { code: \"NetworkError\", retryable: true },\n TimeoutError: { code: \"NetworkError\", retryable: true },\n};\n\nconst PG_SQLSTATE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n \"23505\": { code: \"Conflict\", retryable: false },\n};\n\nconst SQLITE_CODE_TO_CODE: Readonly<Record<string, CodeMapping>> = {\n SQLITE_CONSTRAINT_UNIQUE: { code: \"Conflict\", retryable: false },\n SQLITE_CONSTRAINT_PRIMARYKEY: { code: \"Conflict\", retryable: false },\n};\n\n/* ---------------------------------------------------------------- *\n * Public mappers *\n * ---------------------------------------------------------------- */\n\nconst toCause = (code: string, message: string, extra?: Record<string, unknown>) => ({\n code,\n message,\n ...(extra ?? {}),\n});\n\nconst fallback = (err: unknown): FileSystemError =>\n new FileSystemError({\n code: \"InternalError\",\n message: err instanceof Error ? err.message : String(err),\n retryable: true,\n cause: toCause(\n \"Unknown\",\n err instanceof Error ? err.message : String(err),\n ),\n });\n\nexport const fromAws = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const awsErr = err as {\n name?: unknown;\n message?: unknown;\n $metadata?: { httpStatusCode?: unknown };\n };\n const name = typeof awsErr.name === \"string\" ? awsErr.name : undefined;\n const message =\n typeof awsErr.message === \"string\" ? awsErr.message : `AWS error: ${name ?? \"unknown\"}`;\n const status =\n typeof awsErr.$metadata?.httpStatusCode === \"number\"\n ? awsErr.$metadata.httpStatusCode\n : undefined;\n\n const cause = toCause(\n name ?? (status !== undefined ? String(status) : \"Unknown\"),\n message,\n status !== undefined ? { httpStatusCode: status } : undefined,\n );\n\n // 1) name-based mapping wins (more specific than HTTP status)\n if (name && name in AWS_NAME_TO_CODE) {\n const m = AWS_NAME_TO_CODE[name]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 2) HTTP status mapping\n if (status !== undefined && status in HTTP_STATUS_TO_CODE) {\n const m = HTTP_STATUS_TO_CODE[status]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n // 3) 5xx bucket\n if (status !== undefined && status >= 500 && status < 600) {\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n }\n\n // 4) anything else 4xx-shaped\n if (status !== undefined && status >= 400 && status < 500) {\n return new FileSystemError({ code: \"Forbidden\", message, retryable: false, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromPg = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const pgErr = err as { code?: unknown; message?: unknown };\n const sqlstate = typeof pgErr.code === \"string\" ? pgErr.code : undefined;\n const message =\n typeof pgErr.message === \"string\" ? pgErr.message : `Postgres error: ${sqlstate ?? \"unknown\"}`;\n const cause = toCause(sqlstate ?? \"Unknown\", message);\n\n if (sqlstate && sqlstate in PG_SQLSTATE_TO_CODE) {\n const m = PG_SQLSTATE_TO_CODE[sqlstate]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n\nexport const fromSqlite = (err: unknown): FileSystemError => {\n if (err instanceof FileSystemError) return err;\n\n if (typeof err !== \"object\" || err === null) return fallback(err);\n\n const sqlErr = err as { code?: unknown; message?: unknown };\n const code = typeof sqlErr.code === \"string\" ? sqlErr.code : undefined;\n const message =\n typeof sqlErr.message === \"string\" ? sqlErr.message : `SQLite error: ${code ?? \"unknown\"}`;\n const cause = toCause(code ?? \"Unknown\", message);\n\n if (code && code in SQLITE_CODE_TO_CODE) {\n const m = SQLITE_CODE_TO_CODE[code]!;\n return new FileSystemError({ code: m.code, message, retryable: m.retryable, cause });\n }\n\n return new FileSystemError({ code: \"InternalError\", message, retryable: true, cause });\n};\n","/**\n * FileSystemError — the single error class every adapter, store,\n * server action, and route handler in `file-next` returns or throws.\n *\n * Spec reference: requirement \"FileSystemError discriminated union\"\n * in `sdd/file-next/spec`. The 11 codes are the CLOSED set; any\n * provider-specific code (e.g. S3 `NoSuchKey`, Postgres `23505`) is\n * preserved on `cause.code` so callers can still distinguish upstream\n * reasons while the top-level `code` stays in the catalog.\n *\n * The catalog is a merge of spec + impl: the 6 fixed codes\n * (NotFound, Forbidden, Conflict, QuotaExceeded, NetworkError,\n * InternalError) are non-negotiable; the remaining 5 keep the wire\n * aligned with both the HTTP boundary (route handlers map the\n * top-level `code` to a status directly) and the storage boundary\n * (`RateLimited` and `ChecksumMismatch` carry semantics that have\n * no natural HTTP equivalent). See\n * `sdd/file-next/decisions/error-codes-deviation` for the\n * deviation log and rationale.\n *\n * Retryability table is the design's `error-mapping` excerpt; see\n * `sdd/file-next/design` §C. Any future code MUST add an entry in\n * `RETRYABLE_BY_CODE` (the catalog test enforces this).\n *\n * The placeholder from T-006 is replaced by this file in T-007a.\n * The upstream mappers (fromAws / fromPg / fromSqlite) land in T-007b\n * in `mappers.ts`.\n */\n\nexport const FILE_SYSTEM_ERROR_CODES = [\n \"NotFound\",\n \"Forbidden\",\n \"Conflict\",\n \"QuotaExceeded\",\n \"NetworkError\",\n \"InternalError\",\n \"Unauthorized\",\n \"PayloadTooLarge\",\n \"UnsupportedMediaType\",\n \"RateLimited\",\n \"ChecksumMismatch\",\n] as const satisfies readonly string[];\n\nexport type FileSystemErrorCode = (typeof FILE_SYSTEM_ERROR_CODES)[number];\n\nexport const RETRYABLE_BY_CODE: Readonly<Record<FileSystemErrorCode, boolean>> = {\n NotFound: false,\n Forbidden: false,\n Conflict: false,\n QuotaExceeded: true,\n NetworkError: true,\n InternalError: true,\n Unauthorized: false,\n PayloadTooLarge: false,\n UnsupportedMediaType: false,\n RateLimited: true,\n ChecksumMismatch: true,\n};\n\nexport interface FileSystemErrorOptions {\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport interface FileSystemErrorJson {\n name: string;\n code: FileSystemErrorCode;\n message: string;\n retryable: boolean;\n cause?: { code: string; message: string; [k: string]: unknown };\n}\n\nexport class FileSystemError extends Error {\n readonly code: FileSystemErrorCode;\n readonly retryable: boolean;\n override readonly cause?: { code: string; message: string; [k: string]: unknown };\n\n constructor(opts: FileSystemErrorOptions) {\n super(opts.message);\n this.name = \"FileSystemError\";\n this.code = opts.code;\n this.retryable = opts.retryable;\n if (opts.cause !== undefined) {\n this.cause = opts.cause;\n }\n }\n\n /**\n * Stable JSON shape for RSC pass-through. Error.prototype.message\n * is non-enumerable, so plain `JSON.stringify(err)` would emit `{}`\n * and lose the message + code + retryable flag. `cause` is omitted\n * entirely (not set to undefined) when absent so the shape stays\n * stable for hash-based caches.\n */\n toJSON(): FileSystemErrorJson {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n };\n }\n\n /**\n * Mappers from upstream error shapes (AWS SDK v3, node-postgres,\n * better-sqlite3) to FileSystemError. See `./mappers.ts` for the\n * mapping tables. Re-exposed as static methods so callers can pick\n * the import style that fits; the free functions are the canonical\n * implementation.\n */\n static fromAws(err: unknown): FileSystemError {\n // Lazy import via the runtime binding avoids the static-field\n // circular-dep trap in ESM. The mapper file imports this class\n // for instanceof checks; we look up the function at call time.\n return _fromAws(err);\n }\n\n static fromPg(err: unknown): FileSystemError {\n return _fromPg(err);\n }\n\n static fromSqlite(err: unknown): FileSystemError {\n return _fromSqlite(err);\n }\n}\n\n// Imported here as bindings (not values) so the static methods above\n// can resolve them lazily. The actual implementation lives in mappers.ts.\nimport { fromAws as _fromAws, fromPg as _fromPg, fromSqlite as _fromSqlite } from \"./mappers\";\nexport { fromAws, fromPg, fromSqlite } from \"./mappers\";\n","/**\n * Branded string types and their constructors/guards.\n *\n * Brands are TypeScript-only fictions: a `Path` and an `S3Key` are\n * both strings at runtime, but the type system treats them as\n * distinct nominal types so the compiler catches accidental\n * cross-assignment (e.g. passing an S3Key where a TenantId is\n * expected).\n *\n * Conventions:\n * - `as*` is a zero-cost cast: trust the caller, brand the value.\n * Use it at trust boundaries you have already validated.\n * - `assert*` is a runtime guard: throws TypeError on invalid\n * input. Use it at the edge (parsing user/env input).\n *\n * Validation rules are intentionally minimal in v0.1 and can be\n * tightened as the spec evolves. None of them touch the network or\n * allocate; they are safe in hot paths.\n */\n\nexport type Path = string & { readonly __brand: \"Path\" };\nexport type Prefix = string & { readonly __brand: \"Prefix\" };\nexport type S3Key = string & { readonly __brand: \"S3Key\" };\nexport type TenantId = string & { readonly __brand: \"TenantId\" };\nexport type UserId = string & { readonly __brand: \"UserId\" };\n\n/**\n * POSIX file path. Non-empty, '/' is allowed as the root.\n */\nexport const asPath = (s: string): Path => s as Path;\nexport const assertPath = (s: string): Path => {\n if (s.length === 0) {\n throw new TypeError(\"Path must be a non-empty string\");\n }\n return s as Path;\n};\n\n/**\n * S3 prefix. Empty string is the root prefix. Non-empty prefixes\n * MUST end with '/' so concatenation with a key never produces\n * 'usersfile.jpg' by accident.\n */\nexport const asPrefix = (s: string): Prefix => s as Prefix;\nexport const assertPrefix = (s: string): Prefix => {\n if (s.length > 0 && !s.endsWith(\"/\")) {\n throw new TypeError(\n `Prefix must end with \"/\" or be empty: ${JSON.stringify(s)}`,\n );\n }\n return s as Prefix;\n};\n\n/**\n * S3 object key. No leading slash, no empty segments, no '..' hops.\n */\nexport const asS3Key = (s: string): S3Key => s as S3Key;\nexport const assertS3Key = (s: string): S3Key => {\n if (s.length === 0) {\n throw new TypeError(\"S3Key must be a non-empty string\");\n }\n if (s.startsWith(\"/\")) {\n throw new TypeError(\n `S3Key must not start with a slash: ${JSON.stringify(s)}`,\n );\n }\n if (s.includes(\"..\")) {\n throw new TypeError(\n `S3Key must not contain '..' segments: ${JSON.stringify(s)}`,\n );\n }\n return s as S3Key;\n};\n\n/**\n * Tenant identifier. Alphanumerics, dashes, underscores only.\n */\nexport const asTenantId = (s: string): TenantId => s as TenantId;\nexport const assertTenantId = (s: string): TenantId => {\n if (s.length === 0 || !/^[a-zA-Z0-9_-]+$/.test(s)) {\n throw new TypeError(`Invalid TenantId: ${JSON.stringify(s)}`);\n }\n return s as TenantId;\n};\n\n/**\n * Opaque user identifier. Non-empty; the format is provider-defined.\n */\nexport const asUserId = (s: string): UserId => s as UserId;\nexport const assertUserId = (s: string): UserId => {\n if (s.length === 0) {\n throw new TypeError(\"UserId must be a non-empty string\");\n }\n return s as UserId;\n};\n","/**\n * WriteThrough — keeps object storage and the metadata tree in lockstep.\n *\n * Object keys are the node UUID. Rename/move stay metadata-only.\n * Copy writes a new object under a new UUID.\n */\nimport { ok, err, type Result } from \"@/types/result\";\nimport { FileSystemError } from \"@/errors\";\nimport { asS3Key, asTenantId, asUserId, type S3Key, type TenantId } from \"@/types/branded\";\nimport type { FileSystem } from \"../storage/filesystem\";\nimport type { MetadataStore, FileNode, CreateNodeInput } from \"../metadata/store\";\n\nexport type OrphanOp = \"delete\" | \"restore\";\n\nexport interface PendingOrphan {\n readonly id: string;\n readonly tenantId: TenantId;\n readonly s3Key: S3Key;\n readonly op: OrphanOp;\n readonly createdAt: Date;\n readonly reason: string;\n readonly nodeId?: string;\n}\n\nexport interface WriteThroughFileInput {\n readonly tenantId: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly body: Uint8Array | ReadableStream<Uint8Array>;\n readonly contentType: string;\n readonly metadata?: Readonly<Record<string, string>>;\n readonly ownerId?: string;\n readonly maxBytes?: number;\n readonly id?: string;\n}\n\nexport interface DeleteThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly recursive?: boolean;\n}\n\nexport interface CopyThroughFileInput {\n readonly tenantId: string;\n readonly id: string;\n readonly newParentId: string | null;\n readonly newName?: string;\n}\n\nexport interface ConfirmUploadInput {\n readonly tenantId: string;\n readonly id: string;\n readonly parentId: string | null;\n readonly name: string;\n readonly contentType?: string;\n readonly size?: number;\n readonly ownerId?: string;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface ReconcileReport {\n readonly orphans: ReadonlyArray<PendingOrphan>;\n readonly scanned: number;\n readonly missingInS3: ReadonlyArray<string>;\n readonly orphansInS3: ReadonlyArray<string>;\n readonly fixed: number;\n}\n\nconst bootedTenants = new Set<string>();\n\nexport const __resetDrainState = (): void => {\n bootedTenants.clear();\n};\n\nconst newId = (): string =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : `node-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n\nconst scopedFs = (fs: FileSystem, tenantId: string): FileSystem =>\n fs.tenantId === tenantId ? fs : fs.forTenant(tenantId);\n\nconst bodySize = (body: WriteThroughFileInput[\"body\"]): number => {\n const maybe = body as { byteLength?: number };\n return typeof maybe.byteLength === \"number\" ? maybe.byteLength : 0;\n};\n\nconst drainPendingOrphansFor = async (\n fs: FileSystem,\n store: MetadataStore,\n tenantId: TenantId,\n): Promise<void> => {\n if (bootedTenants.has(tenantId)) return;\n bootedTenants.add(tenantId);\n const result = await store.listPendingOrphans({ tenantId });\n if (!result.ok) return;\n const adapter = scopedFs(fs, tenantId).adapter;\n for (const orphan of result.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n await store.deleteOrphan({ tenantId, id: orphan.id });\n }\n};\n\nexport const createWriteThrough = (\n fs: FileSystem,\n store: MetadataStore,\n): {\n writeThroughFile: (\n input: WriteThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n deleteThroughFile: (\n input: DeleteThroughFileInput,\n ) => Promise<Result<void, FileSystemError>>;\n purgeThroughFile: (\n input: { tenantId: string; id: string },\n ) => Promise<Result<void, FileSystemError>>;\n copyThroughFile: (\n input: CopyThroughFileInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n confirmUpload: (\n input: ConfirmUploadInput,\n ) => Promise<Result<FileNode, FileSystemError>>;\n reconcile: (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }) => Promise<Result<ReconcileReport, FileSystemError>>;\n getOrphans: () => ReadonlyArray<PendingOrphan>;\n} => {\n const writeThroughFile = async (\n input: WriteThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const id = input.id ?? newId();\n const s3Key = asS3Key(id);\n const calcSize = bodySize(input.body);\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + calcSize > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n const w = await adapter.write({\n key: s3Key,\n body: input.body,\n contentType: input.contentType,\n metadata: input.metadata,\n });\n if (!w.ok) return w;\n\n const ownerId = input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\");\n const createInput: CreateNodeInput = {\n id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size: calcSize,\n mimeType: input.contentType,\n s3Key,\n ownerId,\n metadata: input.metadata,\n };\n const c = await store.createNode(createInput);\n if (!c.ok) {\n const enqueue = await store.enqueueOrphan({\n tenantId,\n s3Key,\n reason: c.error.message,\n });\n if (!enqueue.ok) {\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded, metadata insert failed, and orphan enqueue failed: ${enqueue.error.message}; original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n await adapter.delete({ key: s3Key });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `S3 write succeeded but metadata insert failed; orphan logged for reconcile. S3 cleanup attempted. Original: ${c.error.message}`,\n retryable: false,\n }),\n );\n }\n\n return ok(c.value);\n };\n\n const deleteThroughFile = async (\n input: DeleteThroughFileInput,\n ): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const node = g.value;\n const d = await store.deleteNode({\n tenantId,\n id: input.id,\n recursive: input.recursive,\n });\n if (!d.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key || node.id),\n metadataId: input.id,\n reason: d.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata soft-delete failed; orphan logged. Original: ${d.error.message}`,\n retryable: false,\n }),\n );\n }\n\n if (node.kind === \"file\" && node.s3Key) {\n const del = await adapter.delete({ key: asS3Key(node.s3Key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(node.s3Key),\n metadataId: input.id,\n reason: del.error.message,\n });\n return err(\n new FileSystemError({\n code: \"InternalError\",\n message: `Metadata deleted but S3 delete failed; orphan logged. Original: ${del.error.message}`,\n retryable: false,\n }),\n );\n }\n }\n\n return ok(undefined);\n };\n\n const purgeThroughFile = async (input: {\n tenantId: string;\n id: string;\n }): Promise<Result<void, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const purged = await store.purgeNode({ tenantId, id: input.id });\n if (!purged.ok) return purged;\n for (const key of purged.value.s3Keys) {\n const del = await adapter.delete({ key: asS3Key(key) });\n if (!del.ok) {\n await store.enqueueOrphan({\n tenantId,\n s3Key: asS3Key(key),\n metadataId: input.id,\n reason: del.error.message,\n });\n }\n }\n return ok(undefined);\n };\n\n const copyThroughFile = async (\n input: CopyThroughFileInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const g = await store.getNode({ tenantId, id: input.id });\n if (!g.ok) return g;\n if (!g.value) {\n return err(\n new FileSystemError({\n code: \"NotFound\",\n message: `Node ${input.id} not found`,\n retryable: false,\n }),\n );\n }\n const src = g.value;\n const id = newId();\n if (src.kind === \"file\" && src.s3Key) {\n const copied = await adapter.copy({\n sourceKey: asS3Key(src.s3Key),\n destinationKey: asS3Key(id),\n });\n if (!copied.ok) return copied;\n }\n return store.createNode({\n id,\n tenantId,\n parentId: input.newParentId,\n name: input.newName ?? src.name,\n kind: src.kind,\n size: src.size,\n mimeType: src.mimeType,\n s3Key: src.kind === \"file\" ? id : \"\",\n ownerId: src.ownerId,\n metadata: src.metadata,\n });\n };\n\n const confirmUpload = async (\n input: ConfirmUploadInput,\n ): Promise<Result<FileNode, FileSystemError>> => {\n const tenantId = asTenantId(input.tenantId);\n await drainPendingOrphansFor(fs, store, tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const existing = await store.findByS3Key({ tenantId, s3Key: input.id });\n if (existing.ok && existing.value) return ok(existing.value);\n\n const st = await adapter.stat({ key: asS3Key(input.id) });\n const size = st.ok ? st.value.size : (input.size ?? 0);\n const mimeType = input.contentType ?? (st.ok ? st.value.contentType : \"\");\n if (!st.ok && input.size === undefined) return st;\n\n if (fs.quotaBytes != null) {\n const used = await store.sumSize({ tenantId });\n if (!used.ok) return used;\n if (used.value + size > fs.quotaBytes) {\n return err(\n new FileSystemError({\n code: \"QuotaExceeded\",\n message: `Tenant quota of ${fs.quotaBytes} bytes exceeded`,\n retryable: false,\n }),\n );\n }\n }\n\n return store.createNode({\n id: input.id,\n tenantId,\n parentId: input.parentId,\n name: input.name,\n kind: \"file\",\n size,\n mimeType,\n s3Key: input.id,\n ownerId: input.ownerId ? asUserId(input.ownerId) : asUserId(\"system\"),\n metadata: input.metadata,\n });\n };\n\n const reconcile = async (input?: {\n tenantId?: string;\n dryRun?: boolean;\n }): Promise<Result<ReconcileReport, FileSystemError>> => {\n if (!input?.tenantId) {\n return ok({\n orphans: [],\n scanned: 0,\n missingInS3: [],\n orphansInS3: [],\n fixed: 0,\n });\n }\n const tenantId = asTenantId(input.tenantId);\n const adapter = scopedFs(fs, tenantId).adapter;\n const dryRun = input.dryRun === true;\n let fixed = 0;\n\n const pending = await store.listPendingOrphans({ tenantId });\n if (!pending.ok) return pending;\n if (!dryRun) {\n for (const orphan of pending.value) {\n await adapter.delete({ key: asS3Key(orphan.s3Key) });\n const del = await store.deleteOrphan({ tenantId, id: orphan.id });\n if (del.ok) fixed += 1;\n }\n }\n\n const keys = await store.scanFileKeys({ tenantId });\n if (!keys.ok) return keys;\n const missingInS3: string[] = [];\n for (const row of keys.value) {\n const exists = await adapter.exists({ key: asS3Key(row.s3Key) });\n if (exists.ok && !exists.value.exists) missingInS3.push(row.s3Key);\n }\n\n const listed = await adapter.list({ prefix: \"\" as never });\n const orphansInS3: string[] = [];\n if (listed.ok) {\n const known = new Set(keys.value.map((k) => k.s3Key));\n for (const item of listed.value.items) {\n if (!known.has(item.key)) orphansInS3.push(item.key);\n }\n }\n\n return ok({\n orphans: pending.value.map((orphan) => ({\n id: orphan.id,\n tenantId: orphan.tenantId,\n s3Key: orphan.s3Key,\n op: \"delete\" as const,\n createdAt: orphan.createdAt,\n reason: orphan.reason,\n nodeId: orphan.metadataId ?? undefined,\n })),\n scanned: keys.value.length,\n missingInS3,\n orphansInS3,\n fixed,\n });\n };\n\n return {\n writeThroughFile,\n deleteThroughFile,\n purgeThroughFile,\n copyThroughFile,\n confirmUpload,\n reconcile,\n getOrphans: () => [],\n };\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { T as TenantId, U as UserId } from './filesystem-BbZJLy4A.cjs';
1
+ import { T as TenantId, U as UserId } from './filesystem-CewcaWEl.cjs';
2
2
 
3
3
  /**
4
4
  * withAuth — opt-in request wrapper. Resolves the caller; 401 if null.
@@ -1,4 +1,4 @@
1
- import { T as TenantId, U as UserId } from './filesystem-D1Jjx3md.js';
1
+ import { T as TenantId, U as UserId } from './filesystem-B0bJh8bW.js';
2
2
 
3
3
  /**
4
4
  * withAuth — opt-in request wrapper. Resolves the caller; 401 if null.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vryzel/file-next",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "File-system abstraction over AWS S3 / Cloudflare R2 for Next.js, with a secondary metadata index and shadcn/ui components.",
5
5
  "type": "module",
6
6
  "license": "MIT",