@nestm/storage 0.1.0-alpha.6 → 0.1.0-alpha.8

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +398 -19
  3. package/SECURITY.md +69 -0
  4. package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts +74 -0
  5. package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts.map +1 -0
  6. package/dist/ai-sdk/ai-sdk-workspace-tools.js +414 -0
  7. package/dist/ai-sdk/ai-sdk-workspace-tools.js.map +1 -0
  8. package/dist/ai-sdk/index.d.ts +2 -0
  9. package/dist/ai-sdk/index.d.ts.map +1 -0
  10. package/dist/ai-sdk/index.js +2 -0
  11. package/dist/ai-sdk/index.js.map +1 -0
  12. package/dist/files-sdk/files-sdk.driver.d.ts +64 -6
  13. package/dist/files-sdk/files-sdk.driver.d.ts.map +1 -1
  14. package/dist/files-sdk/files-sdk.driver.js +918 -38
  15. package/dist/files-sdk/files-sdk.driver.js.map +1 -1
  16. package/dist/files-sdk/fs/index.d.ts +21 -2
  17. package/dist/files-sdk/fs/index.d.ts.map +1 -1
  18. package/dist/files-sdk/fs/index.js +833 -1
  19. package/dist/files-sdk/fs/index.js.map +1 -1
  20. package/dist/files-sdk/index.d.ts +1 -1
  21. package/dist/files-sdk/index.d.ts.map +1 -1
  22. package/dist/files-sdk/index.js.map +1 -1
  23. package/dist/files-sdk/provider/index.d.ts +9 -5
  24. package/dist/files-sdk/provider/index.d.ts.map +1 -1
  25. package/dist/files-sdk/provider/index.js +60 -15
  26. package/dist/files-sdk/provider/index.js.map +1 -1
  27. package/dist/files-sdk/s3/construction-metadata.d.ts +7 -0
  28. package/dist/files-sdk/s3/construction-metadata.d.ts.map +1 -0
  29. package/dist/files-sdk/s3/construction-metadata.js +13 -0
  30. package/dist/files-sdk/s3/construction-metadata.js.map +1 -0
  31. package/dist/files-sdk/s3/index.d.ts +43 -14
  32. package/dist/files-sdk/s3/index.d.ts.map +1 -1
  33. package/dist/files-sdk/s3/index.js +1046 -57
  34. package/dist/files-sdk/s3/index.js.map +1 -1
  35. package/dist/gateway/storage-gateway.controller.d.ts.map +1 -1
  36. package/dist/gateway/storage-gateway.controller.js +25 -5
  37. package/dist/gateway/storage-gateway.controller.js.map +1 -1
  38. package/dist/storage-etag.d.ts +13 -0
  39. package/dist/storage-etag.d.ts.map +1 -0
  40. package/dist/storage-etag.js +31 -0
  41. package/dist/storage-etag.js.map +1 -0
  42. package/dist/storage.client.d.ts +7 -1
  43. package/dist/storage.client.d.ts.map +1 -1
  44. package/dist/storage.client.js +124 -10
  45. package/dist/storage.client.js.map +1 -1
  46. package/dist/storage.driver.d.ts +23 -1
  47. package/dist/storage.driver.d.ts.map +1 -1
  48. package/dist/storage.driver.js.map +1 -1
  49. package/dist/storage.service.d.ts.map +1 -1
  50. package/dist/storage.service.js +28 -3
  51. package/dist/storage.service.js.map +1 -1
  52. package/dist/storage.types.d.ts +113 -6
  53. package/dist/storage.types.d.ts.map +1 -1
  54. package/dist/storage.types.js.map +1 -1
  55. package/dist/testing/index.d.ts +1 -0
  56. package/dist/testing/index.d.ts.map +1 -1
  57. package/dist/testing/index.js +1 -0
  58. package/dist/testing/index.js.map +1 -1
  59. package/dist/testing/provider-conformance.d.ts +65 -0
  60. package/dist/testing/provider-conformance.d.ts.map +1 -0
  61. package/dist/testing/provider-conformance.js +853 -0
  62. package/dist/testing/provider-conformance.js.map +1 -0
  63. package/dist/workspace/index.d.ts +5 -0
  64. package/dist/workspace/index.d.ts.map +1 -0
  65. package/dist/workspace/index.js +5 -0
  66. package/dist/workspace/index.js.map +1 -0
  67. package/dist/workspace/storage-workspace.cursor.d.ts +71 -0
  68. package/dist/workspace/storage-workspace.cursor.d.ts.map +1 -0
  69. package/dist/workspace/storage-workspace.cursor.js +408 -0
  70. package/dist/workspace/storage-workspace.cursor.js.map +1 -0
  71. package/dist/workspace/storage-workspace.d.ts +6 -0
  72. package/dist/workspace/storage-workspace.d.ts.map +1 -0
  73. package/dist/workspace/storage-workspace.error.d.ts +28 -0
  74. package/dist/workspace/storage-workspace.error.d.ts.map +1 -0
  75. package/dist/workspace/storage-workspace.error.js +67 -0
  76. package/dist/workspace/storage-workspace.error.js.map +1 -0
  77. package/dist/workspace/storage-workspace.js +755 -0
  78. package/dist/workspace/storage-workspace.js.map +1 -0
  79. package/dist/workspace/storage-workspace.path.d.ts +9 -0
  80. package/dist/workspace/storage-workspace.path.d.ts.map +1 -0
  81. package/dist/workspace/storage-workspace.path.js +68 -0
  82. package/dist/workspace/storage-workspace.path.js.map +1 -0
  83. package/dist/workspace/storage-workspace.types.d.ts +105 -0
  84. package/dist/workspace/storage-workspace.types.d.ts.map +1 -0
  85. package/dist/workspace/storage-workspace.types.js +21 -0
  86. package/dist/workspace/storage-workspace.types.js.map +1 -0
  87. package/package.json +24 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-workspace.js","sourceRoot":"","sources":["../../src/workspace/storage-workspace.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageClient } from '../storage.client.js';\nimport { isCanonicalStorageEtag } from '../storage-etag.js';\nimport { StorageErrorCode } from '../storage.error.js';\nimport type {\n StorageObjectMetadata,\n StorageOperationOptions,\n StorageUploadResult,\n} from '../storage.types.js';\n\nimport {\n STORAGE_WORKSPACE_MAX_CURSOR_BYTES,\n decodeStorageWorkspaceCursor,\n issueStorageWorkspaceCursor,\n resolveStorageWorkspaceCursorConfiguration,\n} from './storage-workspace.cursor.js';\nimport type { StorageWorkspaceCursorConfiguration } from './storage-workspace.cursor.js';\nimport {\n sanitizeWorkspaceError,\n workspaceError,\n} from './storage-workspace.error.js';\nimport {\n assertWorkspacePath,\n containsControlCharacter,\n isPathInside,\n joinWorkspacePath,\n workspaceBasename,\n} from './storage-workspace.path.js';\nimport {\n DEFAULT_STORAGE_WORKSPACE_LIMITS,\n STORAGE_WORKSPACE_PERMISSIONS,\n} from './storage-workspace.types.js';\nimport type {\n MountStorageWorkspaceOptions,\n StorageWorkspace as StorageWorkspaceContract,\n StorageWorkspaceBody,\n StorageWorkspaceDirectory,\n StorageWorkspaceEntry,\n StorageWorkspaceFile,\n StorageWorkspaceLimits,\n StorageWorkspaceListOptions,\n StorageWorkspaceMountOptions,\n StorageWorkspaceMutationOptions,\n StorageWorkspacePage,\n StorageWorkspacePermission,\n StorageWorkspaceReadOptions,\n StorageWorkspaceSearchMatch,\n StorageWorkspaceSearchOptions,\n StorageWorkspaceTextFile,\n StorageWorkspaceWriteOptions,\n} from './storage-workspace.types.js';\n\nconst DEFAULT_PERMISSIONS: ReadonlySet<StorageWorkspacePermission> = new Set([\n 'list',\n 'read',\n 'search',\n]);\nconst PERMISSION_VALUES = new Set<StorageWorkspacePermission>(\n STORAGE_WORKSPACE_PERMISSIONS,\n);\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder('utf-8', { fatal: true });\nconst WORKSPACE_CONSTRUCTOR = Symbol('StorageWorkspace.constructor');\n\ninterface WorkspaceState {\n readonly client: StorageClient;\n readonly cursor: Readonly<StorageWorkspaceCursorConfiguration> | undefined;\n readonly prefix: string;\n}\n\ninterface SearchPageState {\n readonly backendCursor: string | undefined;\n readonly scanned: number;\n}\n\nfunction operationOptions(\n options?: StorageOperationOptions,\n): StorageOperationOptions | undefined {\n if (options === undefined) {\n return undefined;\n }\n return {\n ...(options.retries !== undefined && { retries: options.retries }),\n ...(options.signal !== undefined && { signal: options.signal }),\n ...(options.timeout !== undefined && { timeout: options.timeout }),\n };\n}\n\nfunction positiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `${label} must be a positive safe integer.`,\n { permanent: true },\n );\n }\n return value;\n}\n\nfunction assertEtag(etag: string, operation: string): void {\n if (!isCanonicalStorageEtag(etag)) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `${operation} requires a canonical bare etag of at most 1,024 bytes.`,\n { permanent: true },\n );\n }\n}\n\nfunction resolveLimits(\n requested: Partial<StorageWorkspaceLimits> | undefined,\n parent?: Readonly<StorageWorkspaceLimits>,\n): Readonly<StorageWorkspaceLimits> {\n const baseline = parent ?? DEFAULT_STORAGE_WORKSPACE_LIMITS;\n const next: StorageWorkspaceLimits = {\n cursorTtlMs: requested?.cursorTtlMs ?? baseline.cursorTtlMs,\n maxCursorBytes: requested?.maxCursorBytes ?? baseline.maxCursorBytes,\n maxPageSize: requested?.maxPageSize ?? baseline.maxPageSize,\n maxPathBytes: requested?.maxPathBytes ?? baseline.maxPathBytes,\n maxReadBytes: requested?.maxReadBytes ?? baseline.maxReadBytes,\n maxSearchResults: requested?.maxSearchResults ?? baseline.maxSearchResults,\n maxSearchScan: requested?.maxSearchScan ?? baseline.maxSearchScan,\n maxWriteBytes: requested?.maxWriteBytes ?? baseline.maxWriteBytes,\n };\n for (const [name, value] of Object.entries(next)) {\n positiveSafeInteger(value, `limits.${name}`);\n const parentValue = baseline[name as keyof StorageWorkspaceLimits];\n if (parent !== undefined && value > parentValue) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `Child workspace limit \"${name}\" cannot exceed its parent limit.`,\n { permanent: true },\n );\n }\n }\n if (next.maxCursorBytes > STORAGE_WORKSPACE_MAX_CURSOR_BYTES) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `limits.maxCursorBytes cannot exceed ${STORAGE_WORKSPACE_MAX_CURSOR_BYTES}.`,\n { permanent: true },\n );\n }\n return Object.freeze(next);\n}\n\nfunction resolvePermissions(\n requested: Iterable<StorageWorkspacePermission> | undefined,\n parent?: ReadonlySet<StorageWorkspacePermission>,\n): ReadonlySet<StorageWorkspacePermission> {\n const baseline = parent ?? DEFAULT_PERMISSIONS;\n const values = requested === undefined ? [...baseline] : [...requested];\n const permissions = new Set<StorageWorkspacePermission>();\n for (const permission of values) {\n if (!PERMISSION_VALUES.has(permission)) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `Unknown workspace permission \"${String(permission)}\".`,\n { permanent: true },\n );\n }\n if (parent !== undefined && !parent.has(permission)) {\n throw workspaceError(\n StorageErrorCode.UNAUTHORIZED,\n `Child workspace cannot add the \"${permission}\" permission.`,\n { permanent: true },\n );\n }\n permissions.add(permission);\n }\n return permissions;\n}\n\nfunction logicalFile(\n metadata: StorageObjectMetadata | StorageUploadResult,\n path: string,\n): StorageWorkspaceFile {\n if (\n !Number.isSafeInteger(metadata.size) ||\n metadata.size < 0 ||\n typeof metadata.contentType !== 'string' ||\n metadata.contentType.length === 0 ||\n (metadata.etag !== undefined && !isCanonicalStorageEtag(metadata.etag)) ||\n (metadata.lastModified !== undefined &&\n !Number.isFinite(new Date(metadata.lastModified).getTime()))\n ) {\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Storage provider returned malformed file metadata.',\n { permanent: true },\n );\n }\n return {\n contentType: metadata.contentType,\n ...(metadata.etag !== undefined && { etag: metadata.etag }),\n kind: 'file',\n ...(metadata.lastModified !== undefined && {\n lastModified: new Date(metadata.lastModified),\n }),\n name: workspaceBasename(path),\n path,\n size: metadata.size,\n };\n}\n\nfunction logicalDirectory(path: string): StorageWorkspaceDirectory {\n const normalized = path.endsWith('/') ? path.slice(0, -1) : path;\n return {\n kind: 'directory',\n name: normalized.length === 0 ? '' : workspaceBasename(normalized),\n path: normalized,\n };\n}\n\nfunction segmentGlobMatches(pattern: string, value: string): boolean {\n let patternIndex = 0;\n let valueIndex = 0;\n let starIndex = -1;\n let starValueIndex = -1;\n while (valueIndex < value.length) {\n if (\n patternIndex < pattern.length &&\n (pattern[patternIndex] === '?' ||\n pattern[patternIndex] === value[valueIndex])\n ) {\n patternIndex += 1;\n valueIndex += 1;\n } else if (pattern[patternIndex] === '*') {\n starIndex = patternIndex;\n patternIndex += 1;\n starValueIndex = valueIndex;\n } else if (starIndex !== -1) {\n patternIndex = starIndex + 1;\n starValueIndex += 1;\n valueIndex = starValueIndex;\n } else {\n return false;\n }\n }\n while (pattern[patternIndex] === '*') {\n patternIndex += 1;\n }\n return patternIndex === pattern.length;\n}\n\nfunction globMatches(pattern: string, value: string): boolean {\n const patternSegments = pattern.split('/');\n const valueSegments = value.split('/');\n let patternIndex = 0;\n let valueIndex = 0;\n let globstarIndex = -1;\n let globstarValueIndex = -1;\n while (valueIndex < valueSegments.length) {\n const patternSegment = patternSegments[patternIndex];\n const valueSegment = valueSegments[valueIndex];\n if (patternSegment === '**') {\n globstarIndex = patternIndex;\n globstarValueIndex = valueIndex;\n patternIndex += 1;\n } else if (\n patternSegment !== undefined &&\n valueSegment !== undefined &&\n segmentGlobMatches(patternSegment, valueSegment)\n ) {\n patternIndex += 1;\n valueIndex += 1;\n } else if (globstarIndex !== -1) {\n patternIndex = globstarIndex + 1;\n globstarValueIndex += 1;\n valueIndex = globstarValueIndex;\n } else {\n return false;\n }\n }\n while (patternSegments[patternIndex] === '**') {\n patternIndex += 1;\n }\n return patternIndex === patternSegments.length;\n}\n\nfunction searchMatches(\n query: string,\n path: string,\n match: StorageWorkspaceSearchMatch,\n caseInsensitive: boolean,\n): boolean {\n const candidate = caseInsensitive ? path.toLowerCase() : path;\n const needle = caseInsensitive ? query.toLowerCase() : query;\n if (match === 'exact') {\n return candidate === needle;\n }\n if (match === 'substring') {\n return candidate.includes(needle);\n }\n return globMatches(needle, candidate);\n}\n\nasync function collectBoundedText(\n stream: ReadableStream<Uint8Array>,\n announcedSize: number,\n maxBytes: number,\n path: string,\n): Promise<string> {\n if (announcedSize > maxBytes) {\n await stream.cancel().catch(() => undefined);\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Workspace file \"${path}\" exceeds the ${maxBytes}-byte read limit.`,\n { path, permanent: true },\n );\n }\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n if (result.value.byteLength === 0) {\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Storage provider returned an empty non-terminal body chunk.',\n { path, permanent: true },\n );\n }\n size += result.value.byteLength;\n if (size > maxBytes) {\n await reader.cancel().catch(() => undefined);\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Workspace file \"${path}\" exceeded the ${maxBytes}-byte read limit.`,\n { path, permanent: true },\n );\n }\n chunks.push(result.value);\n }\n } finally {\n reader.releaseLock();\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n try {\n return decoder.decode(bytes);\n } catch {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `Workspace file \"${path}\" is not valid UTF-8 text.`,\n { path, permanent: true },\n );\n }\n}\n\nasync function collectBoundedBytes(\n stream: ReadableStream<Uint8Array>,\n announcedSize: number,\n maxBytes: number,\n path: string,\n): Promise<Uint8Array> {\n if (announcedSize > maxBytes) {\n await stream.cancel().catch(() => undefined);\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Workspace file \"${path}\" exceeds the ${maxBytes}-byte copy limit.`,\n { path, permanent: true },\n );\n }\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n if (result.value.byteLength === 0) {\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Storage provider returned an empty non-terminal body chunk.',\n { path, permanent: true },\n );\n }\n size += result.value.byteLength;\n if (size > maxBytes) {\n await reader.cancel().catch(() => undefined);\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Workspace file \"${path}\" exceeded the ${maxBytes}-byte copy limit.`,\n { path, permanent: true },\n );\n }\n chunks.push(result.value);\n }\n } finally {\n reader.releaseLock();\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}\n\nclass StorageWorkspaceImplementation implements StorageWorkspaceContract {\n readonly #state: WorkspaceState;\n readonly #permissions: ReadonlySet<StorageWorkspacePermission>;\n readonly #limits: Readonly<StorageWorkspaceLimits>;\n\n /** @internal Construct workspaces through {@link mountStorageWorkspace}. */\n constructor(\n constructorToken: symbol,\n state: WorkspaceState,\n permissions: ReadonlySet<StorageWorkspacePermission>,\n limits: Readonly<StorageWorkspaceLimits>,\n ) {\n if (constructorToken !== WORKSPACE_CONSTRUCTOR) {\n throw workspaceError(\n StorageErrorCode.UNAUTHORIZED,\n 'StorageWorkspace must be created by mountStorageWorkspace().',\n { permanent: true },\n );\n }\n this.#state = state;\n this.#permissions = permissions;\n this.#limits = limits;\n }\n\n get permissions(): ReadonlySet<StorageWorkspacePermission> {\n return new Set(this.#permissions);\n }\n\n get limits(): Readonly<StorageWorkspaceLimits> {\n return Object.freeze({ ...this.#limits });\n }\n\n allows(permission: StorageWorkspacePermission): boolean {\n return this.#permissions.has(permission);\n }\n\n async stat(\n path: string,\n options?: StorageOperationOptions,\n ): Promise<StorageWorkspaceFile> {\n this.#require('read');\n const logicalPath = this.#filePath(path);\n try {\n const metadata = await this.#state.client.head(\n this.#scope(logicalPath),\n options,\n );\n this.#assertResultPath(metadata.key, logicalPath);\n return logicalFile(metadata, logicalPath);\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'stat',\n path: logicalPath,\n });\n }\n }\n\n async readText(\n path: string,\n options?: StorageWorkspaceReadOptions,\n ): Promise<StorageWorkspaceTextFile> {\n this.#require('read');\n const logicalPath = this.#filePath(path);\n const maxBytes = options?.maxBytes ?? this.#limits.maxReadBytes;\n positiveSafeInteger(maxBytes, 'maxBytes');\n if (maxBytes > this.#limits.maxReadBytes) {\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `maxBytes cannot exceed the ${this.#limits.maxReadBytes}-byte workspace read limit.`,\n { path: logicalPath, permanent: true },\n );\n }\n try {\n const object = await this.#state.client.downloadStream(\n this.#scope(logicalPath),\n operationOptions(options),\n );\n this.#assertResultPath(object.key, logicalPath);\n const text = await collectBoundedText(\n object.body,\n object.size,\n maxBytes,\n logicalPath,\n );\n return { ...logicalFile(object, logicalPath), text };\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'read',\n path: logicalPath,\n });\n }\n }\n\n async list(\n options: StorageWorkspaceListOptions = {},\n ): Promise<StorageWorkspacePage> {\n this.#require('list');\n const continuation =\n options.cursor !== undefined\n ? await decodeStorageWorkspaceCursor(\n this.#state.cursor,\n this.#cursorBinding(),\n 'list',\n options.cursor,\n )\n : undefined;\n if (\n continuation !== undefined &&\n ((options.directory !== undefined &&\n options.directory !== continuation.directory) ||\n (options.limit !== undefined && options.limit !== continuation.limit) ||\n (options.recursive !== undefined &&\n options.recursive !== continuation.recursive))\n ) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Workspace cursor conflicts with the supplied list query.',\n { permanent: true },\n );\n }\n const directory = this.#directoryPath(\n continuation?.directory ?? options.directory ?? '',\n );\n const limit = this.#pageLimit(\n continuation?.limit ?? options.limit,\n this.#limits.maxPageSize,\n );\n const recursive = continuation?.recursive ?? options.recursive === true;\n const scopedDirectory = this.#scopeDirectory(directory);\n try {\n const page = await this.#state.client.list({\n ...(continuation !== undefined && {\n cursor: continuation.backendCursor,\n }),\n ...(!recursive && { delimiter: '/' }),\n limit,\n ...operationOptions(options),\n prefix: scopedDirectory,\n });\n if (page.items.length + (page.prefixes?.length ?? 0) > limit) {\n this.#malformedPage();\n }\n if (page.cursor !== undefined && page.cursor.length === 0) {\n this.#malformedPage();\n }\n if (\n page.cursor !== undefined &&\n (page.items.length + (page.prefixes?.length ?? 0) === 0 ||\n page.cursor === continuation?.backendCursor)\n ) {\n this.#malformedPage();\n }\n const entries: StorageWorkspaceEntry[] = [];\n for (const item of page.items) {\n const path = this.#unscoped(item.key);\n if (!isPathInside(directory, path)) {\n this.#providerScopeFailure();\n }\n if (!recursive) {\n const relative =\n directory.length === 0 ? path : path.slice(directory.length + 1);\n if (relative.includes('/')) {\n this.#malformedPage();\n }\n }\n entries.push(logicalFile(item, path));\n }\n for (const prefix of page.prefixes ?? []) {\n const path = this.#unscoped(\n prefix.endsWith('/') ? prefix.slice(0, -1) : prefix,\n );\n if (!isPathInside(directory, path)) {\n this.#providerScopeFailure();\n }\n if (!recursive) {\n const relative =\n directory.length === 0 ? path : path.slice(directory.length + 1);\n if (relative.includes('/')) {\n this.#malformedPage();\n }\n }\n entries.push(logicalDirectory(path));\n }\n return {\n ...(page.cursor !== undefined && {\n cursor: await issueStorageWorkspaceCursor(\n this.#state.cursor,\n this.#cursorBinding(),\n {\n backendCursor: page.cursor,\n directory,\n limit,\n operation: 'list',\n recursive,\n },\n ),\n }),\n entries,\n };\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'list',\n ...(directory.length > 0 && { path: directory }),\n });\n }\n }\n\n async search(\n query: string,\n options: StorageWorkspaceSearchOptions = {},\n ): Promise<StorageWorkspacePage> {\n this.#require('search');\n const continuation =\n options.cursor !== undefined\n ? await decodeStorageWorkspaceCursor(\n this.#state.cursor,\n this.#cursorBinding(),\n 'search',\n options.cursor,\n )\n : undefined;\n if (\n continuation !== undefined &&\n ((query.length > 0 && query !== continuation.query) ||\n (options.directory !== undefined &&\n options.directory !== continuation.directory) ||\n (options.match !== undefined && options.match !== continuation.match) ||\n (options.caseInsensitive !== undefined &&\n options.caseInsensitive !== continuation.caseInsensitive) ||\n (options.limit !== undefined && options.limit !== continuation.limit))\n ) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Workspace cursor conflicts with the supplied search query.',\n { permanent: true },\n );\n }\n query = continuation?.query ?? query;\n if (typeof query !== 'string' || query.length === 0) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Search query must be a non-empty string.',\n { permanent: true },\n );\n }\n if (query.includes('\\\\') || containsControlCharacter(query)) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Search query contains forbidden characters.',\n { permanent: true },\n );\n }\n if (encoder.encode(query).byteLength > this.#limits.maxPathBytes) {\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n 'Search query exceeds the workspace path-byte limit.',\n { permanent: true },\n );\n }\n const directory = this.#directoryPath(\n continuation?.directory ?? options.directory ?? '',\n );\n const match = continuation?.match ?? options.match ?? 'glob';\n if (match !== 'glob' && match !== 'substring' && match !== 'exact') {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Search match must be glob, substring, or exact.',\n { permanent: true },\n );\n }\n const caseInsensitive =\n continuation?.caseInsensitive ?? options.caseInsensitive === true;\n const limit = this.#pageLimit(\n continuation?.limit ?? options.limit,\n this.#limits.maxSearchResults,\n );\n const prior: SearchPageState = {\n backendCursor: continuation?.backendCursor,\n scanned: continuation?.scanned ?? 0,\n };\n return this.#searchPage(query, {\n caseInsensitive,\n directory,\n limit,\n match,\n operation: operationOptions(options),\n state: prior,\n });\n }\n\n async writeFile(\n path: string,\n body: StorageWorkspaceBody,\n options: StorageWorkspaceWriteOptions,\n ): Promise<StorageWorkspaceFile> {\n this.#require(options.mode);\n const logicalPath = this.#filePath(path);\n if (typeof body !== 'string' && !(body instanceof Uint8Array)) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'Workspace writes accept only strings or Uint8Array bodies.',\n { path: logicalPath, permanent: true },\n );\n }\n const size =\n typeof body === 'string'\n ? encoder.encode(body).byteLength\n : body.byteLength;\n if (size > this.#limits.maxWriteBytes) {\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Workspace write exceeds the ${this.#limits.maxWriteBytes}-byte limit.`,\n { path: logicalPath, permanent: true },\n );\n }\n if (options.mode === 'replace') {\n assertEtag(options.etag, 'Replace');\n }\n try {\n const common = {\n ...(options.contentType !== undefined && {\n contentType: options.contentType,\n }),\n ...(options.metadata !== undefined && { metadata: options.metadata }),\n ...operationOptions(options),\n };\n const result =\n options.mode === 'create'\n ? await this.#state.client.uploadConditional(\n this.#scope(logicalPath),\n body,\n { ...common, condition: { type: 'create' } },\n )\n : await this.#state.client.uploadConditional(\n this.#scope(logicalPath),\n body,\n {\n ...common,\n condition: { etag: options.etag, type: 'replace' },\n },\n );\n this.#assertResultPath(result.key, logicalPath);\n return logicalFile(result, logicalPath);\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: options.mode,\n path: logicalPath,\n });\n }\n }\n\n async copyFile(\n source: string,\n destination: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<StorageWorkspaceFile> {\n this.#require('copy');\n this.#require('read');\n this.#require('create');\n const sourcePath = this.#filePath(source, 'source path');\n const destinationPath = this.#filePath(destination, 'destination path');\n if (sourcePath === destinationPath) {\n throw workspaceError(\n StorageErrorCode.CONFLICT,\n 'Copy destination must differ from its source.',\n { path: destinationPath, permanent: true },\n );\n }\n assertEtag(options.etag, 'Copy');\n const capabilities = this.#state.client.capabilities;\n if (\n capabilities.conditionalCreate?.resultEtag !== true ||\n capabilities.conditionalRead?.etag !== true\n ) {\n throw workspaceError(\n StorageErrorCode.NOT_SUPPORTED,\n 'Safe copy requires exact-ETag reads and create-only uploads that return an ETag.',\n { operation: 'copy', path: destinationPath, permanent: true },\n );\n }\n return this.#copyCreate(sourcePath, destinationPath, options);\n }\n\n async moveFile(\n source: string,\n destination: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<StorageWorkspaceFile> {\n this.#require('move');\n this.#require('read');\n this.#require('create');\n this.#require('delete');\n const capabilities = this.#state.client.capabilities;\n if (\n capabilities.conditionalCreate?.resultEtag !== true ||\n capabilities.conditionalDelete?.etag !== true ||\n capabilities.conditionalRead?.etag !== true\n ) {\n throw workspaceError(\n StorageErrorCode.NOT_SUPPORTED,\n 'Safe move requires exact-ETag reads, create-only uploads that return an ETag, and conditional delete.',\n { operation: 'move', permanent: true },\n );\n }\n const sourcePath = this.#filePath(source, 'source path');\n const destinationPath = this.#filePath(destination, 'destination path');\n if (sourcePath === destinationPath) {\n throw workspaceError(\n StorageErrorCode.CONFLICT,\n 'Move destination must differ from its source.',\n { path: destinationPath, permanent: true },\n );\n }\n assertEtag(options.etag, 'Move');\n const copied = await this.#copyCreate(sourcePath, destinationPath, options);\n if (copied.etag === undefined) {\n throw workspaceError(\n StorageErrorCode.NOT_SUPPORTED,\n 'Safe move requires the destination provider to return an etag.',\n { path: destinationPath, permanent: true },\n );\n }\n try {\n await this.#state.client.deleteConditional(this.#scope(sourcePath), {\n condition: { etag: options.etag },\n ...operationOptions(options),\n });\n return copied;\n } catch {\n throw workspaceError(\n StorageErrorCode.CONFLICT,\n `Workspace move could not confirm source deletion; destination \"${destinationPath}\" was retained. Inspect both paths before retrying.`,\n {\n operation: 'move',\n path: destinationPath,\n permanent: true,\n },\n );\n }\n }\n\n async deleteFile(\n path: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<void> {\n this.#require('delete');\n const logicalPath = this.#filePath(path);\n assertEtag(options.etag, 'Delete');\n try {\n await this.#state.client.deleteConditional(this.#scope(logicalPath), {\n condition: { etag: options.etag },\n ...operationOptions(options),\n });\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'delete',\n path: logicalPath,\n });\n }\n }\n\n mount(\n directory: string,\n options: StorageWorkspaceMountOptions = {},\n ): StorageWorkspaceContract {\n const path = this.#directoryPath(directory);\n if (path.length === 0) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n 'A child workspace mount directory must not be empty.',\n { permanent: true },\n );\n }\n return new StorageWorkspaceImplementation(\n WORKSPACE_CONSTRUCTOR,\n {\n ...this.#state,\n prefix: joinWorkspacePath(this.#state.prefix, path),\n },\n resolvePermissions(options.permissions, this.#permissions),\n resolveLimits(options.limits, this.#limits),\n );\n }\n\n async #copyCreate(\n sourcePath: string,\n destinationPath: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<StorageWorkspaceFile> {\n try {\n const source = await this.#state.client.downloadConditional(\n this.#scope(sourcePath),\n {\n condition: { etag: options.etag },\n ...operationOptions(options),\n },\n );\n this.#assertResultPath(source.key, sourcePath);\n if (source.etag !== options.etag) {\n await source.body.cancel().catch(() => undefined);\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Conditional read returned an unexpected source ETag.',\n { operation: 'copy', path: sourcePath, permanent: true },\n );\n }\n const bytes = await collectBoundedBytes(\n source.body,\n source.size,\n this.#limits.maxWriteBytes,\n sourcePath,\n );\n const result = await this.#state.client.uploadConditional(\n this.#scope(destinationPath),\n bytes,\n {\n condition: { type: 'create' },\n contentType: source.contentType,\n ...(source.metadata !== undefined && { metadata: source.metadata }),\n ...operationOptions(options),\n },\n );\n this.#assertResultPath(result.key, destinationPath);\n return logicalFile(result, destinationPath);\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'copy',\n path: destinationPath,\n });\n }\n }\n\n async #searchPage(\n query: string,\n context: {\n caseInsensitive: boolean;\n directory: string;\n limit: number;\n match: StorageWorkspaceSearchMatch;\n operation: StorageOperationOptions | undefined;\n state: SearchPageState;\n },\n ): Promise<StorageWorkspacePage> {\n const entries: StorageWorkspaceEntry[] = [];\n let backendCursor = context.state.backendCursor;\n let scanned = context.state.scanned;\n try {\n while (\n entries.length < context.limit &&\n scanned < this.#limits.maxSearchScan\n ) {\n const remaining = this.#limits.maxSearchScan - scanned;\n const remainingResults = context.limit - entries.length;\n const page = await this.#state.client.list({\n ...(backendCursor !== undefined && { cursor: backendCursor }),\n limit: Math.min(\n this.#limits.maxPageSize,\n remaining,\n remainingResults,\n ),\n ...context.operation,\n prefix: this.#scopeDirectory(context.directory),\n });\n const requested = Math.min(\n this.#limits.maxPageSize,\n remaining,\n remainingResults,\n );\n if (page.items.length > requested) {\n this.#malformedPage();\n }\n if ((page.prefixes?.length ?? 0) > 0) {\n this.#malformedPage();\n }\n if (page.cursor !== undefined && page.cursor.length === 0) {\n this.#malformedPage();\n }\n if (\n page.cursor !== undefined &&\n (page.items.length === 0 || page.cursor === backendCursor)\n ) {\n this.#malformedPage();\n }\n for (let index = 0; index < page.items.length; index += 1) {\n const item = page.items[index];\n if (item === undefined) {\n continue;\n }\n scanned += 1;\n const path = this.#unscoped(item.key);\n if (!isPathInside(context.directory, path)) {\n this.#providerScopeFailure();\n }\n if (\n searchMatches(\n query,\n context.directory.length === 0\n ? path\n : path.slice(context.directory.length + 1),\n context.match,\n context.caseInsensitive,\n )\n ) {\n entries.push(logicalFile(item, path));\n }\n if (\n entries.length === context.limit ||\n scanned === this.#limits.maxSearchScan\n ) {\n break;\n }\n }\n backendCursor = page.cursor;\n if (backendCursor === undefined) {\n break;\n }\n }\n const hasMore = backendCursor !== undefined;\n if (scanned >= this.#limits.maxSearchScan && hasMore) {\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `Search exceeded the ${this.#limits.maxSearchScan}-object scan limit.`,\n { permanent: true },\n );\n }\n const nextBackendCursor = backendCursor;\n return {\n ...(nextBackendCursor !== undefined && {\n cursor: await issueStorageWorkspaceCursor(\n this.#state.cursor,\n this.#cursorBinding(),\n {\n backendCursor: nextBackendCursor,\n caseInsensitive: context.caseInsensitive,\n directory: context.directory,\n limit: context.limit,\n match: context.match,\n operation: 'search',\n query,\n scanned,\n },\n ),\n }),\n entries,\n };\n } catch (error) {\n throw sanitizeWorkspaceError(error, {\n operation: 'search',\n ...(context.directory.length > 0 && { path: context.directory }),\n });\n }\n }\n\n #require(permission: StorageWorkspacePermission): void {\n if (!this.#permissions.has(permission)) {\n throw workspaceError(\n StorageErrorCode.UNAUTHORIZED,\n `Workspace does not allow ${permission} operations.`,\n { permanent: true },\n );\n }\n }\n\n #filePath(path: string, label = 'path'): string {\n return assertWorkspacePath(path, this.#limits.maxPathBytes, {\n allowRoot: false,\n label,\n });\n }\n\n #directoryPath(path: string): string {\n return assertWorkspacePath(path, this.#limits.maxPathBytes, {\n allowRoot: true,\n label: 'directory',\n });\n }\n\n #scope(path: string): string {\n return `${this.#state.prefix}/${path}`;\n }\n\n #scopeDirectory(directory: string): string {\n return directory.length === 0\n ? `${this.#state.prefix}/`\n : `${this.#state.prefix}/${directory}/`;\n }\n\n #unscoped(key: string): string {\n const scoped = `${this.#state.prefix}/`;\n if (!key.startsWith(scoped)) {\n this.#providerScopeFailure();\n }\n const path = key.slice(scoped.length);\n return assertWorkspacePath(path, this.#limits.maxPathBytes, {\n allowRoot: false,\n label: 'backend result path',\n });\n }\n\n #assertResultPath(key: string, expected: string): void {\n if (this.#unscoped(key) !== expected) {\n this.#providerScopeFailure();\n }\n }\n\n #providerScopeFailure(): never {\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Storage provider returned data outside the mounted workspace.',\n { permanent: true },\n );\n }\n\n #malformedPage(): never {\n throw workspaceError(\n StorageErrorCode.PROVIDER,\n 'Storage provider returned a malformed workspace page.',\n { permanent: true },\n );\n }\n\n #pageLimit(value: number | undefined, maximum: number): number {\n const limit = value ?? maximum;\n positiveSafeInteger(limit, 'limit');\n if (limit > maximum) {\n throw workspaceError(\n StorageErrorCode.LIMIT_EXCEEDED,\n `limit cannot exceed the workspace maximum of ${maximum}.`,\n { permanent: true },\n );\n }\n return limit;\n }\n\n #cursorBinding(): {\n readonly limits: Readonly<StorageWorkspaceLimits>;\n readonly prefix: string;\n readonly store: string;\n } {\n return {\n limits: this.#limits,\n prefix: this.#state.prefix,\n store: this.#state.client.name,\n };\n }\n}\n\nexport function mountStorageWorkspace(\n client: StorageClient,\n options: MountStorageWorkspaceOptions,\n): StorageWorkspaceContract {\n const limits = resolveLimits(options.limits);\n const prefix = assertWorkspacePath(options.prefix, limits.maxPathBytes, {\n allowRoot: false,\n label: 'workspace prefix',\n });\n return new StorageWorkspaceImplementation(\n WORKSPACE_CONSTRUCTOR,\n {\n client,\n cursor: resolveStorageWorkspaceCursorConfiguration(options.cursor),\n prefix,\n },\n resolvePermissions(options.permissions),\n limits,\n );\n}\n\n/** @deprecated Prefer {@link mountStorageWorkspace}. */\nexport const createStorageWorkspace = mountStorageWorkspace;\n"]}
@@ -0,0 +1,9 @@
1
+ export declare function containsControlCharacter(value: string): boolean;
2
+ export declare function assertWorkspacePath(value: string, maxBytes: number, options: {
3
+ allowRoot: boolean;
4
+ label?: string;
5
+ }): string;
6
+ export declare function workspaceBasename(path: string): string;
7
+ export declare function joinWorkspacePath(directory: string, path: string): string;
8
+ export declare function isPathInside(directory: string, path: string): boolean;
9
+ //# sourceMappingURL=storage-workspace.path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-workspace.path.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-workspace.path.ts"],"names":[],"mappings":"AASA,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAUD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,MAAM,CA8CR;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAErE"}
@@ -0,0 +1,68 @@
1
+ import { StorageErrorCode } from '../storage.error.js';
2
+ import { workspaceError } from './storage-workspace.error.js';
3
+ const FORBIDDEN_UNICODE_CHARACTER = /\p{C}/u;
4
+ const WINDOWS_DEVICE_NAME = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/iu;
5
+ const encoder = new TextEncoder();
6
+ export function containsControlCharacter(value) {
7
+ return FORBIDDEN_UNICODE_CHARACTER.test(value);
8
+ }
9
+ function invalidPath(label, reason) {
10
+ throw workspaceError(StorageErrorCode.INVALID_ARGUMENT, `${label} ${reason}.`, { permanent: true });
11
+ }
12
+ export function assertWorkspacePath(value, maxBytes, options) {
13
+ const label = options.label ?? 'path';
14
+ if (typeof value !== 'string') {
15
+ invalidPath(label, 'must be a string');
16
+ }
17
+ if (value.length === 0) {
18
+ if (options.allowRoot) {
19
+ return '';
20
+ }
21
+ invalidPath(label, 'must not be empty');
22
+ }
23
+ if (value.startsWith('/')) {
24
+ invalidPath(label, 'must be relative');
25
+ }
26
+ if (value !== value.normalize('NFC')) {
27
+ invalidPath(label, 'must use NFC Unicode normalization');
28
+ }
29
+ if (value.includes('\\')) {
30
+ invalidPath(label, 'must use POSIX separators');
31
+ }
32
+ if (containsControlCharacter(value)) {
33
+ invalidPath(label, 'must not contain control characters');
34
+ }
35
+ if (encoder.encode(value).byteLength > maxBytes) {
36
+ invalidPath(label, `exceeds the ${maxBytes}-byte path limit`);
37
+ }
38
+ const segments = value.split('/');
39
+ for (const segment of segments) {
40
+ if (segment.length === 0) {
41
+ invalidPath(label, 'must not contain empty path segments');
42
+ }
43
+ if (segment === '.' || segment === '..') {
44
+ invalidPath(label, 'must not contain . or .. segments');
45
+ }
46
+ if (segment.includes(':')) {
47
+ invalidPath(label, 'must not contain colon characters');
48
+ }
49
+ if (segment.endsWith('.') || segment.endsWith(' ')) {
50
+ invalidPath(label, 'segments must not end with a dot or space');
51
+ }
52
+ if (WINDOWS_DEVICE_NAME.test(segment)) {
53
+ invalidPath(label, 'must not contain a reserved device segment');
54
+ }
55
+ }
56
+ return value;
57
+ }
58
+ export function workspaceBasename(path) {
59
+ const separator = path.lastIndexOf('/');
60
+ return separator === -1 ? path : path.slice(separator + 1);
61
+ }
62
+ export function joinWorkspacePath(directory, path) {
63
+ return directory.length === 0 ? path : `${directory}/${path}`;
64
+ }
65
+ export function isPathInside(directory, path) {
66
+ return directory.length === 0 || path.startsWith(`${directory}/`);
67
+ }
68
+ //# sourceMappingURL=storage-workspace.path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-workspace.path.js","sourceRoot":"","sources":["../../src/workspace/storage-workspace.path.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageErrorCode } from '../storage.error.js';\n\nimport { workspaceError } from './storage-workspace.error.js';\n\nconst FORBIDDEN_UNICODE_CHARACTER = /\\p{C}/u;\nconst WINDOWS_DEVICE_NAME =\n /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\..*)?$/iu;\nconst encoder = new TextEncoder();\n\nexport function containsControlCharacter(value: string): boolean {\n return FORBIDDEN_UNICODE_CHARACTER.test(value);\n}\n\nfunction invalidPath(label: string, reason: string): never {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `${label} ${reason}.`,\n { permanent: true },\n );\n}\n\nexport function assertWorkspacePath(\n value: string,\n maxBytes: number,\n options: { allowRoot: boolean; label?: string },\n): string {\n const label = options.label ?? 'path';\n if (typeof value !== 'string') {\n invalidPath(label, 'must be a string');\n }\n if (value.length === 0) {\n if (options.allowRoot) {\n return '';\n }\n invalidPath(label, 'must not be empty');\n }\n if (value.startsWith('/')) {\n invalidPath(label, 'must be relative');\n }\n if (value !== value.normalize('NFC')) {\n invalidPath(label, 'must use NFC Unicode normalization');\n }\n if (value.includes('\\\\')) {\n invalidPath(label, 'must use POSIX separators');\n }\n if (containsControlCharacter(value)) {\n invalidPath(label, 'must not contain control characters');\n }\n if (encoder.encode(value).byteLength > maxBytes) {\n invalidPath(label, `exceeds the ${maxBytes}-byte path limit`);\n }\n\n const segments = value.split('/');\n for (const segment of segments) {\n if (segment.length === 0) {\n invalidPath(label, 'must not contain empty path segments');\n }\n if (segment === '.' || segment === '..') {\n invalidPath(label, 'must not contain . or .. segments');\n }\n if (segment.includes(':')) {\n invalidPath(label, 'must not contain colon characters');\n }\n if (segment.endsWith('.') || segment.endsWith(' ')) {\n invalidPath(label, 'segments must not end with a dot or space');\n }\n if (WINDOWS_DEVICE_NAME.test(segment)) {\n invalidPath(label, 'must not contain a reserved device segment');\n }\n }\n return value;\n}\n\nexport function workspaceBasename(path: string): string {\n const separator = path.lastIndexOf('/');\n return separator === -1 ? path : path.slice(separator + 1);\n}\n\nexport function joinWorkspacePath(directory: string, path: string): string {\n return directory.length === 0 ? path : `${directory}/${path}`;\n}\n\nexport function isPathInside(directory: string, path: string): boolean {\n return directory.length === 0 || path.startsWith(`${directory}/`);\n}\n"]}
@@ -0,0 +1,105 @@
1
+ import type { StorageBody, StorageOperationOptions } from '../storage.types.js';
2
+ import type { StorageWorkspaceCursorConfiguration } from './storage-workspace.cursor.js';
3
+ export declare const STORAGE_WORKSPACE_PERMISSIONS: readonly ['list', 'read', 'search', 'create', 'replace', 'copy', 'move', 'delete'];
4
+ export type StorageWorkspacePermission = (typeof STORAGE_WORKSPACE_PERMISSIONS)[number];
5
+ export interface StorageWorkspaceLimits {
6
+ /** Maximum UTF-8 byte length of an opaque continuation cursor. */
7
+ maxCursorBytes: number;
8
+ /** Maximum UTF-8 byte length of a workspace-relative path. */
9
+ maxPathBytes: number;
10
+ /** Maximum bytes returned by a buffered text read. */
11
+ maxReadBytes: number;
12
+ /** Maximum bytes accepted by one write. */
13
+ maxWriteBytes: number;
14
+ /** Maximum entries returned by one list page. */
15
+ maxPageSize: number;
16
+ /** Maximum entries returned by one search page. */
17
+ maxSearchResults: number;
18
+ /** Maximum objects inspected by one search query across all pages. */
19
+ maxSearchScan: number;
20
+ /**
21
+ * Authorization ceiling for an opaque continuation cursor. It does not
22
+ * extend the lifetime or availability of an embedded provider cursor.
23
+ */
24
+ cursorTtlMs: number;
25
+ }
26
+ export declare const DEFAULT_STORAGE_WORKSPACE_LIMITS: Readonly<StorageWorkspaceLimits>;
27
+ export interface StorageWorkspaceFile {
28
+ kind: 'file';
29
+ path: string;
30
+ name: string;
31
+ size: number;
32
+ contentType: string;
33
+ etag?: string;
34
+ lastModified?: Date;
35
+ }
36
+ export interface StorageWorkspaceDirectory {
37
+ kind: 'directory';
38
+ path: string;
39
+ name: string;
40
+ }
41
+ export type StorageWorkspaceEntry = StorageWorkspaceFile | StorageWorkspaceDirectory;
42
+ export interface StorageWorkspaceTextFile extends StorageWorkspaceFile {
43
+ text: string;
44
+ }
45
+ export interface StorageWorkspacePage {
46
+ entries: StorageWorkspaceEntry[];
47
+ cursor?: string;
48
+ }
49
+ export interface StorageWorkspaceMountOptions {
50
+ permissions?: Iterable<StorageWorkspacePermission>;
51
+ limits?: Partial<StorageWorkspaceLimits>;
52
+ }
53
+ export interface MountStorageWorkspaceOptions extends StorageWorkspaceMountOptions {
54
+ /** Trusted backend namespace. It is never exposed through the workspace. */
55
+ prefix: string;
56
+ /** Stable server-owned cursor configuration shared across serving replicas. */
57
+ cursor?: StorageWorkspaceCursorConfiguration;
58
+ }
59
+ export interface StorageWorkspaceReadOptions extends StorageOperationOptions {
60
+ maxBytes?: number;
61
+ }
62
+ export interface StorageWorkspaceListOptions extends StorageOperationOptions {
63
+ directory?: string | undefined;
64
+ recursive?: boolean | undefined;
65
+ limit?: number | undefined;
66
+ cursor?: string | undefined;
67
+ }
68
+ export type StorageWorkspaceSearchMatch = 'glob' | 'substring' | 'exact';
69
+ export interface StorageWorkspaceSearchOptions extends StorageOperationOptions {
70
+ directory?: string | undefined;
71
+ match?: StorageWorkspaceSearchMatch | undefined;
72
+ caseInsensitive?: boolean | undefined;
73
+ limit?: number | undefined;
74
+ cursor?: string | undefined;
75
+ }
76
+ interface StorageWorkspaceWriteCommon extends StorageOperationOptions {
77
+ contentType?: string;
78
+ metadata?: Record<string, string>;
79
+ }
80
+ export type StorageWorkspaceWriteOptions = StorageWorkspaceWriteCommon & ({
81
+ mode: 'create';
82
+ } | {
83
+ mode: 'replace';
84
+ etag: string;
85
+ });
86
+ export interface StorageWorkspaceMutationOptions extends StorageOperationOptions {
87
+ etag: string;
88
+ }
89
+ export type StorageWorkspaceBody = Extract<StorageBody, string | Uint8Array>;
90
+ export interface StorageWorkspace {
91
+ readonly permissions: ReadonlySet<StorageWorkspacePermission>;
92
+ readonly limits: Readonly<StorageWorkspaceLimits>;
93
+ allows(permission: StorageWorkspacePermission): boolean;
94
+ stat(path: string, options?: StorageOperationOptions): Promise<StorageWorkspaceFile>;
95
+ readText(path: string, options?: StorageWorkspaceReadOptions): Promise<StorageWorkspaceTextFile>;
96
+ list(options?: StorageWorkspaceListOptions): Promise<StorageWorkspacePage>;
97
+ search(query: string, options?: StorageWorkspaceSearchOptions): Promise<StorageWorkspacePage>;
98
+ writeFile(path: string, body: StorageWorkspaceBody, options: StorageWorkspaceWriteOptions): Promise<StorageWorkspaceFile>;
99
+ copyFile(source: string, destination: string, options: StorageWorkspaceMutationOptions): Promise<StorageWorkspaceFile>;
100
+ moveFile(source: string, destination: string, options: StorageWorkspaceMutationOptions): Promise<StorageWorkspaceFile>;
101
+ deleteFile(path: string, options: StorageWorkspaceMutationOptions): Promise<void>;
102
+ mount(directory: string, options?: StorageWorkspaceMountOptions): StorageWorkspace;
103
+ }
104
+ export {};
105
+ //# sourceMappingURL=storage-workspace.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-workspace.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-workspace.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export const STORAGE_WORKSPACE_PERMISSIONS = [
2
+ 'list',
3
+ 'read',
4
+ 'search',
5
+ 'create',
6
+ 'replace',
7
+ 'copy',
8
+ 'move',
9
+ 'delete',
10
+ ];
11
+ export const DEFAULT_STORAGE_WORKSPACE_LIMITS = Object.freeze({
12
+ cursorTtlMs: 5 * 60 * 1000,
13
+ maxCursorBytes: 4_096,
14
+ maxPageSize: 100,
15
+ maxPathBytes: 1024,
16
+ maxReadBytes: 1024 * 1024,
17
+ maxSearchResults: 100,
18
+ maxSearchScan: 1000,
19
+ maxWriteBytes: 1024 * 1024,
20
+ });
21
+ //# sourceMappingURL=storage-workspace.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-workspace.types.js","sourceRoot":"","sources":["../../src/workspace/storage-workspace.types.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,MAAM;IACN,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,MAAM;IACN,MAAM;IACN,QAAQ;CACA,CAAC;AA2BX,MAAM,CAAC,MAAM,gCAAgC,GAC3C,MAAM,CAAC,MAAM,CAAC;IACZ,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;IAC1B,cAAc,EAAE,KAAK;IACrB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI,GAAG,IAAI;IACzB,gBAAgB,EAAE,GAAG;IACrB,aAAa,EAAE,IAAI;IACnB,aAAa,EAAE,IAAI,GAAG,IAAI;CAC3B,CAAC,CAAC","sourcesContent":["import type { StorageBody, StorageOperationOptions } from '../storage.types.js';\n\nimport type { StorageWorkspaceCursorConfiguration } from './storage-workspace.cursor.js';\n\nexport const STORAGE_WORKSPACE_PERMISSIONS = [\n 'list',\n 'read',\n 'search',\n 'create',\n 'replace',\n 'copy',\n 'move',\n 'delete',\n] as const;\n\nexport type StorageWorkspacePermission =\n (typeof STORAGE_WORKSPACE_PERMISSIONS)[number];\n\nexport interface StorageWorkspaceLimits {\n /** Maximum UTF-8 byte length of an opaque continuation cursor. */\n maxCursorBytes: number;\n /** Maximum UTF-8 byte length of a workspace-relative path. */\n maxPathBytes: number;\n /** Maximum bytes returned by a buffered text read. */\n maxReadBytes: number;\n /** Maximum bytes accepted by one write. */\n maxWriteBytes: number;\n /** Maximum entries returned by one list page. */\n maxPageSize: number;\n /** Maximum entries returned by one search page. */\n maxSearchResults: number;\n /** Maximum objects inspected by one search query across all pages. */\n maxSearchScan: number;\n /**\n * Authorization ceiling for an opaque continuation cursor. It does not\n * extend the lifetime or availability of an embedded provider cursor.\n */\n cursorTtlMs: number;\n}\n\nexport const DEFAULT_STORAGE_WORKSPACE_LIMITS: Readonly<StorageWorkspaceLimits> =\n Object.freeze({\n cursorTtlMs: 5 * 60 * 1000,\n maxCursorBytes: 4_096,\n maxPageSize: 100,\n maxPathBytes: 1024,\n maxReadBytes: 1024 * 1024,\n maxSearchResults: 100,\n maxSearchScan: 1000,\n maxWriteBytes: 1024 * 1024,\n });\n\nexport interface StorageWorkspaceFile {\n kind: 'file';\n path: string;\n name: string;\n size: number;\n contentType: string;\n etag?: string;\n lastModified?: Date;\n}\n\nexport interface StorageWorkspaceDirectory {\n kind: 'directory';\n path: string;\n name: string;\n}\n\nexport type StorageWorkspaceEntry =\n StorageWorkspaceFile | StorageWorkspaceDirectory;\n\nexport interface StorageWorkspaceTextFile extends StorageWorkspaceFile {\n text: string;\n}\n\nexport interface StorageWorkspacePage {\n entries: StorageWorkspaceEntry[];\n cursor?: string;\n}\n\nexport interface StorageWorkspaceMountOptions {\n permissions?: Iterable<StorageWorkspacePermission>;\n limits?: Partial<StorageWorkspaceLimits>;\n}\n\nexport interface MountStorageWorkspaceOptions extends StorageWorkspaceMountOptions {\n /** Trusted backend namespace. It is never exposed through the workspace. */\n prefix: string;\n /** Stable server-owned cursor configuration shared across serving replicas. */\n cursor?: StorageWorkspaceCursorConfiguration;\n}\n\nexport interface StorageWorkspaceReadOptions extends StorageOperationOptions {\n maxBytes?: number;\n}\n\nexport interface StorageWorkspaceListOptions extends StorageOperationOptions {\n directory?: string | undefined;\n recursive?: boolean | undefined;\n limit?: number | undefined;\n cursor?: string | undefined;\n}\n\nexport type StorageWorkspaceSearchMatch = 'glob' | 'substring' | 'exact';\n\nexport interface StorageWorkspaceSearchOptions extends StorageOperationOptions {\n directory?: string | undefined;\n match?: StorageWorkspaceSearchMatch | undefined;\n caseInsensitive?: boolean | undefined;\n limit?: number | undefined;\n cursor?: string | undefined;\n}\n\ninterface StorageWorkspaceWriteCommon extends StorageOperationOptions {\n contentType?: string;\n metadata?: Record<string, string>;\n}\n\nexport type StorageWorkspaceWriteOptions = StorageWorkspaceWriteCommon &\n (\n | { mode: 'create' }\n | {\n mode: 'replace';\n etag: string;\n }\n );\n\nexport interface StorageWorkspaceMutationOptions extends StorageOperationOptions {\n etag: string;\n}\n\nexport type StorageWorkspaceBody = Extract<StorageBody, string | Uint8Array>;\n\nexport interface StorageWorkspace {\n readonly permissions: ReadonlySet<StorageWorkspacePermission>;\n readonly limits: Readonly<StorageWorkspaceLimits>;\n allows(permission: StorageWorkspacePermission): boolean;\n stat(\n path: string,\n options?: StorageOperationOptions,\n ): Promise<StorageWorkspaceFile>;\n readText(\n path: string,\n options?: StorageWorkspaceReadOptions,\n ): Promise<StorageWorkspaceTextFile>;\n list(options?: StorageWorkspaceListOptions): Promise<StorageWorkspacePage>;\n search(\n query: string,\n options?: StorageWorkspaceSearchOptions,\n ): Promise<StorageWorkspacePage>;\n writeFile(\n path: string,\n body: StorageWorkspaceBody,\n options: StorageWorkspaceWriteOptions,\n ): Promise<StorageWorkspaceFile>;\n copyFile(\n source: string,\n destination: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<StorageWorkspaceFile>;\n moveFile(\n source: string,\n destination: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<StorageWorkspaceFile>;\n deleteFile(\n path: string,\n options: StorageWorkspaceMutationOptions,\n ): Promise<void>;\n mount(\n directory: string,\n options?: StorageWorkspaceMountOptions,\n ): StorageWorkspace;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nestm/storage",
3
- "version": "0.1.0-alpha.6",
4
- "description": "Framework-neutral storage clients with NestJS 12 integration, named stores, streaming I/O, and an optional guarded HTTP gateway.",
3
+ "version": "0.1.0-alpha.8",
4
+ "description": "Framework-neutral storage clients, capability-scoped agent workspaces, NestJS 12 integration, and guarded HTTP access.",
5
5
  "license": "MIT",
6
6
  "author": "Kauan Guesser",
7
7
  "type": "module",
@@ -23,6 +23,14 @@
23
23
  "types": "./dist/core/index.d.ts",
24
24
  "import": "./dist/core/index.js"
25
25
  },
26
+ "./workspace": {
27
+ "types": "./dist/workspace/index.d.ts",
28
+ "import": "./dist/workspace/index.js"
29
+ },
30
+ "./ai-sdk": {
31
+ "types": "./dist/ai-sdk/index.d.ts",
32
+ "import": "./dist/ai-sdk/index.js"
33
+ },
26
34
  "./files-sdk": {
27
35
  "types": "./dist/files-sdk/index.d.ts",
28
36
  "import": "./dist/files-sdk/index.js"
@@ -70,6 +78,7 @@
70
78
  "nestjs-12",
71
79
  "storage",
72
80
  "object-storage",
81
+ "agent-workspace",
73
82
  "s3",
74
83
  "gcs",
75
84
  "azure",
@@ -81,14 +90,16 @@
81
90
  "files-sdk": "2.2.3"
82
91
  },
83
92
  "peerDependencies": {
84
- "@aws-sdk/client-s3": "^3.700.0",
93
+ "@aws-sdk/client-s3": "^3.919.0",
85
94
  "@aws-sdk/lib-storage": "^3.700.0",
86
95
  "@aws-sdk/s3-presigned-post": "^3.700.0",
87
96
  "@aws-sdk/s3-request-presigner": "^3.700.0",
88
97
  "@nestjs/common": "^12.0.0-alpha.5",
89
98
  "@nestjs/core": "^12.0.0-alpha.5",
99
+ "ai": ">=7.0.0 <8.0.0",
90
100
  "reflect-metadata": "^0.2.2",
91
- "rxjs": "^7.8.1"
101
+ "rxjs": "^7.8.1",
102
+ "zod": "^4.1.8"
92
103
  },
93
104
  "peerDependenciesMeta": {
94
105
  "@aws-sdk/client-s3": {
@@ -109,11 +120,17 @@
109
120
  "@nestjs/core": {
110
121
  "optional": true
111
122
  },
123
+ "ai": {
124
+ "optional": true
125
+ },
112
126
  "reflect-metadata": {
113
127
  "optional": true
114
128
  },
115
129
  "rxjs": {
116
130
  "optional": true
131
+ },
132
+ "zod": {
133
+ "optional": true
117
134
  }
118
135
  },
119
136
  "devDependencies": {
@@ -130,6 +147,7 @@
130
147
  "@types/node": "26.1.2",
131
148
  "@types/supertest": "7.2.1",
132
149
  "@vitest/coverage-v8": "4.1.10",
150
+ "ai": "7.0.64",
133
151
  "fastify": "5.11.2",
134
152
  "oxlint": "1.77.0",
135
153
  "prettier": "3.9.6",
@@ -138,7 +156,8 @@
138
156
  "rxjs": "7.8.2",
139
157
  "supertest": "7.2.2",
140
158
  "typescript": "7.0.2",
141
- "vitest": "4.1.10"
159
+ "vitest": "4.1.10",
160
+ "zod": "4.4.3"
142
161
  },
143
162
  "scripts": {
144
163
  "build": "node scripts/clean.mjs && tsc -p tsconfig.build.json",