@nestm/storage 0.1.0-alpha.7 → 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 (74) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +217 -18
  3. package/SECURITY.md +34 -5
  4. package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts +14 -3
  5. package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts.map +1 -1
  6. package/dist/ai-sdk/ai-sdk-workspace-tools.js +54 -23
  7. package/dist/ai-sdk/ai-sdk-workspace-tools.js.map +1 -1
  8. package/dist/ai-sdk/index.d.ts +1 -1
  9. package/dist/ai-sdk/index.d.ts.map +1 -1
  10. package/dist/ai-sdk/index.js.map +1 -1
  11. package/dist/files-sdk/files-sdk.driver.d.ts +54 -10
  12. package/dist/files-sdk/files-sdk.driver.d.ts.map +1 -1
  13. package/dist/files-sdk/files-sdk.driver.js +784 -63
  14. package/dist/files-sdk/files-sdk.driver.js.map +1 -1
  15. package/dist/files-sdk/fs/index.d.ts +4 -4
  16. package/dist/files-sdk/fs/index.d.ts.map +1 -1
  17. package/dist/files-sdk/fs/index.js +242 -9
  18. package/dist/files-sdk/fs/index.js.map +1 -1
  19. package/dist/files-sdk/index.d.ts +1 -1
  20. package/dist/files-sdk/index.d.ts.map +1 -1
  21. package/dist/files-sdk/index.js.map +1 -1
  22. package/dist/files-sdk/provider/index.d.ts +9 -5
  23. package/dist/files-sdk/provider/index.d.ts.map +1 -1
  24. package/dist/files-sdk/provider/index.js +53 -15
  25. package/dist/files-sdk/provider/index.js.map +1 -1
  26. package/dist/files-sdk/s3/construction-metadata.d.ts +7 -0
  27. package/dist/files-sdk/s3/construction-metadata.d.ts.map +1 -0
  28. package/dist/files-sdk/s3/construction-metadata.js +13 -0
  29. package/dist/files-sdk/s3/construction-metadata.js.map +1 -0
  30. package/dist/files-sdk/s3/index.d.ts +39 -19
  31. package/dist/files-sdk/s3/index.d.ts.map +1 -1
  32. package/dist/files-sdk/s3/index.js +936 -113
  33. package/dist/files-sdk/s3/index.js.map +1 -1
  34. package/dist/gateway/storage-gateway.controller.d.ts.map +1 -1
  35. package/dist/gateway/storage-gateway.controller.js +25 -5
  36. package/dist/gateway/storage-gateway.controller.js.map +1 -1
  37. package/dist/storage-etag.d.ts +13 -0
  38. package/dist/storage-etag.d.ts.map +1 -0
  39. package/dist/storage-etag.js +31 -0
  40. package/dist/storage-etag.js.map +1 -0
  41. package/dist/storage.client.d.ts +3 -1
  42. package/dist/storage.client.d.ts.map +1 -1
  43. package/dist/storage.client.js +87 -22
  44. package/dist/storage.client.js.map +1 -1
  45. package/dist/storage.driver.d.ts +21 -1
  46. package/dist/storage.driver.d.ts.map +1 -1
  47. package/dist/storage.driver.js.map +1 -1
  48. package/dist/storage.types.d.ts +90 -19
  49. package/dist/storage.types.d.ts.map +1 -1
  50. package/dist/storage.types.js.map +1 -1
  51. package/dist/testing/index.d.ts +1 -0
  52. package/dist/testing/index.d.ts.map +1 -1
  53. package/dist/testing/index.js +1 -0
  54. package/dist/testing/index.js.map +1 -1
  55. package/dist/testing/provider-conformance.d.ts +65 -0
  56. package/dist/testing/provider-conformance.d.ts.map +1 -0
  57. package/dist/testing/provider-conformance.js +853 -0
  58. package/dist/testing/provider-conformance.js.map +1 -0
  59. package/dist/workspace/index.d.ts +1 -0
  60. package/dist/workspace/index.d.ts.map +1 -1
  61. package/dist/workspace/index.js +1 -0
  62. package/dist/workspace/index.js.map +1 -1
  63. package/dist/workspace/storage-workspace.cursor.d.ts +68 -3
  64. package/dist/workspace/storage-workspace.cursor.d.ts.map +1 -1
  65. package/dist/workspace/storage-workspace.cursor.js +402 -39
  66. package/dist/workspace/storage-workspace.cursor.js.map +1 -1
  67. package/dist/workspace/storage-workspace.d.ts.map +1 -1
  68. package/dist/workspace/storage-workspace.js +54 -46
  69. package/dist/workspace/storage-workspace.js.map +1 -1
  70. package/dist/workspace/storage-workspace.types.d.ts +10 -2
  71. package/dist/workspace/storage-workspace.types.d.ts.map +1 -1
  72. package/dist/workspace/storage-workspace.types.js +1 -0
  73. package/dist/workspace/storage-workspace.types.js.map +1 -1
  74. package/package.json +3 -3
@@ -1,6 +1,7 @@
1
1
  import { StorageClient } from '../storage.client.js';
2
+ import { isCanonicalStorageEtag } from '../storage-etag.js';
2
3
  import { StorageErrorCode } from '../storage.error.js';
3
- import { StorageWorkspaceCursorStore } from './storage-workspace.cursor.js';
4
+ import { STORAGE_WORKSPACE_MAX_CURSOR_BYTES, decodeStorageWorkspaceCursor, issueStorageWorkspaceCursor, resolveStorageWorkspaceCursorConfiguration, } from './storage-workspace.cursor.js';
4
5
  import { sanitizeWorkspaceError, workspaceError, } from './storage-workspace.error.js';
5
6
  import { assertWorkspacePath, containsControlCharacter, isPathInside, joinWorkspacePath, workspaceBasename, } from './storage-workspace.path.js';
6
7
  import { DEFAULT_STORAGE_WORKSPACE_LIMITS, STORAGE_WORKSPACE_PERMISSIONS, } from './storage-workspace.types.js';
@@ -29,18 +30,16 @@ function positiveSafeInteger(value, label) {
29
30
  }
30
31
  return value;
31
32
  }
32
- function assertEtag(etag, maxBytes, operation) {
33
- if (typeof etag !== 'string' ||
34
- etag.length === 0 ||
35
- containsControlCharacter(etag) ||
36
- encoder.encode(etag).byteLength > maxBytes) {
37
- throw workspaceError(StorageErrorCode.INVALID_ARGUMENT, `${operation} requires a valid non-empty etag.`, { permanent: true });
33
+ function assertEtag(etag, operation) {
34
+ if (!isCanonicalStorageEtag(etag)) {
35
+ throw workspaceError(StorageErrorCode.INVALID_ARGUMENT, `${operation} requires a canonical bare etag of at most 1,024 bytes.`, { permanent: true });
38
36
  }
39
37
  }
40
38
  function resolveLimits(requested, parent) {
41
39
  const baseline = parent ?? DEFAULT_STORAGE_WORKSPACE_LIMITS;
42
40
  const next = {
43
41
  cursorTtlMs: requested?.cursorTtlMs ?? baseline.cursorTtlMs,
42
+ maxCursorBytes: requested?.maxCursorBytes ?? baseline.maxCursorBytes,
44
43
  maxPageSize: requested?.maxPageSize ?? baseline.maxPageSize,
45
44
  maxPathBytes: requested?.maxPathBytes ?? baseline.maxPathBytes,
46
45
  maxReadBytes: requested?.maxReadBytes ?? baseline.maxReadBytes,
@@ -55,6 +54,9 @@ function resolveLimits(requested, parent) {
55
54
  throw workspaceError(StorageErrorCode.INVALID_ARGUMENT, `Child workspace limit "${name}" cannot exceed its parent limit.`, { permanent: true });
56
55
  }
57
56
  }
57
+ if (next.maxCursorBytes > STORAGE_WORKSPACE_MAX_CURSOR_BYTES) {
58
+ throw workspaceError(StorageErrorCode.INVALID_ARGUMENT, `limits.maxCursorBytes cannot exceed ${STORAGE_WORKSPACE_MAX_CURSOR_BYTES}.`, { permanent: true });
59
+ }
58
60
  return Object.freeze(next);
59
61
  }
60
62
  function resolvePermissions(requested, parent) {
@@ -77,8 +79,7 @@ function logicalFile(metadata, path) {
77
79
  metadata.size < 0 ||
78
80
  typeof metadata.contentType !== 'string' ||
79
81
  metadata.contentType.length === 0 ||
80
- (metadata.etag !== undefined &&
81
- (typeof metadata.etag !== 'string' || metadata.etag.length === 0)) ||
82
+ (metadata.etag !== undefined && !isCanonicalStorageEtag(metadata.etag)) ||
82
83
  (metadata.lastModified !== undefined &&
83
84
  !Number.isFinite(new Date(metadata.lastModified).getTime()))) {
84
85
  throw workspaceError(StorageErrorCode.PROVIDER, 'Storage provider returned malformed file metadata.', { permanent: true });
@@ -317,8 +318,8 @@ class StorageWorkspaceImplementation {
317
318
  }
318
319
  async list(options = {}) {
319
320
  this.#require('list');
320
- const continuation = options.cursor
321
- ? this.#state.cursorStore.consume(options.cursor, this.#binding('list'))
321
+ const continuation = options.cursor !== undefined
322
+ ? await decodeStorageWorkspaceCursor(this.#state.cursor, this.#cursorBinding(), 'list', options.cursor)
322
323
  : undefined;
323
324
  if (continuation !== undefined &&
324
325
  ((options.directory !== undefined &&
@@ -331,7 +332,6 @@ class StorageWorkspaceImplementation {
331
332
  const directory = this.#directoryPath(continuation?.directory ?? options.directory ?? '');
332
333
  const limit = this.#pageLimit(continuation?.limit ?? options.limit, this.#limits.maxPageSize);
333
334
  const recursive = continuation?.recursive ?? options.recursive === true;
334
- const binding = this.#binding('list');
335
335
  const scopedDirectory = this.#scopeDirectory(directory);
336
336
  try {
337
337
  const page = await this.#state.client.list({
@@ -383,12 +383,13 @@ class StorageWorkspaceImplementation {
383
383
  }
384
384
  return {
385
385
  ...(page.cursor !== undefined && {
386
- cursor: this.#state.cursorStore.issue(binding, {
386
+ cursor: await issueStorageWorkspaceCursor(this.#state.cursor, this.#cursorBinding(), {
387
387
  backendCursor: page.cursor,
388
388
  directory,
389
389
  limit,
390
+ operation: 'list',
390
391
  recursive,
391
- }, this.#limits.cursorTtlMs),
392
+ }),
392
393
  }),
393
394
  entries,
394
395
  };
@@ -402,8 +403,8 @@ class StorageWorkspaceImplementation {
402
403
  }
403
404
  async search(query, options = {}) {
404
405
  this.#require('search');
405
- const continuation = options.cursor
406
- ? this.#state.cursorStore.consume(options.cursor, this.#binding('search'))
406
+ const continuation = options.cursor !== undefined
407
+ ? await decodeStorageWorkspaceCursor(this.#state.cursor, this.#cursorBinding(), 'search', options.cursor)
407
408
  : undefined;
408
409
  if (continuation !== undefined &&
409
410
  ((query.length > 0 && query !== continuation.query) ||
@@ -432,18 +433,11 @@ class StorageWorkspaceImplementation {
432
433
  }
433
434
  const caseInsensitive = continuation?.caseInsensitive ?? options.caseInsensitive === true;
434
435
  const limit = this.#pageLimit(continuation?.limit ?? options.limit, this.#limits.maxSearchResults);
435
- const binding = this.#binding('search');
436
- const prior = continuation ?? {
437
- backendCursor: undefined,
438
- caseInsensitive,
439
- directory,
440
- limit,
441
- match,
442
- query,
443
- scanned: 0,
436
+ const prior = {
437
+ backendCursor: continuation?.backendCursor,
438
+ scanned: continuation?.scanned ?? 0,
444
439
  };
445
440
  return this.#searchPage(query, {
446
- binding,
447
441
  caseInsensitive,
448
442
  directory,
449
443
  limit,
@@ -465,7 +459,7 @@ class StorageWorkspaceImplementation {
465
459
  throw workspaceError(StorageErrorCode.LIMIT_EXCEEDED, `Workspace write exceeds the ${this.#limits.maxWriteBytes}-byte limit.`, { path: logicalPath, permanent: true });
466
460
  }
467
461
  if (options.mode === 'replace') {
468
- assertEtag(options.etag, this.#limits.maxPathBytes, 'Replace');
462
+ assertEtag(options.etag, 'Replace');
469
463
  }
470
464
  try {
471
465
  const common = {
@@ -500,8 +494,11 @@ class StorageWorkspaceImplementation {
500
494
  if (sourcePath === destinationPath) {
501
495
  throw workspaceError(StorageErrorCode.CONFLICT, 'Copy destination must differ from its source.', { path: destinationPath, permanent: true });
502
496
  }
503
- if (this.#state.client.capabilities.conditionalMutation?.create !== true) {
504
- throw workspaceError(StorageErrorCode.NOT_SUPPORTED, 'Safe copy requires create-only conditional upload support.', { operation: 'copy', path: destinationPath, permanent: true });
497
+ assertEtag(options.etag, 'Copy');
498
+ const capabilities = this.#state.client.capabilities;
499
+ if (capabilities.conditionalCreate?.resultEtag !== true ||
500
+ capabilities.conditionalRead?.etag !== true) {
501
+ throw workspaceError(StorageErrorCode.NOT_SUPPORTED, 'Safe copy requires exact-ETag reads and create-only uploads that return an ETag.', { operation: 'copy', path: destinationPath, permanent: true });
505
502
  }
506
503
  return this.#copyCreate(sourcePath, destinationPath, options);
507
504
  }
@@ -510,18 +507,18 @@ class StorageWorkspaceImplementation {
510
507
  this.#require('read');
511
508
  this.#require('create');
512
509
  this.#require('delete');
513
- const conditional = this.#state.client.capabilities.conditionalMutation;
514
- if (conditional?.create !== true ||
515
- conditional.delete !== true ||
516
- conditional.etag !== true) {
517
- throw workspaceError(StorageErrorCode.NOT_SUPPORTED, 'Safe move requires create-only upload, conditional delete, and upload ETag support.', { operation: 'move', permanent: true });
510
+ const capabilities = this.#state.client.capabilities;
511
+ if (capabilities.conditionalCreate?.resultEtag !== true ||
512
+ capabilities.conditionalDelete?.etag !== true ||
513
+ capabilities.conditionalRead?.etag !== true) {
514
+ throw workspaceError(StorageErrorCode.NOT_SUPPORTED, 'Safe move requires exact-ETag reads, create-only uploads that return an ETag, and conditional delete.', { operation: 'move', permanent: true });
518
515
  }
519
516
  const sourcePath = this.#filePath(source, 'source path');
520
517
  const destinationPath = this.#filePath(destination, 'destination path');
521
518
  if (sourcePath === destinationPath) {
522
519
  throw workspaceError(StorageErrorCode.CONFLICT, 'Move destination must differ from its source.', { path: destinationPath, permanent: true });
523
520
  }
524
- assertEtag(options.etag, this.#limits.maxPathBytes, 'Move');
521
+ assertEtag(options.etag, 'Move');
525
522
  const copied = await this.#copyCreate(sourcePath, destinationPath, options);
526
523
  if (copied.etag === undefined) {
527
524
  throw workspaceError(StorageErrorCode.NOT_SUPPORTED, 'Safe move requires the destination provider to return an etag.', { path: destinationPath, permanent: true });
@@ -544,7 +541,7 @@ class StorageWorkspaceImplementation {
544
541
  async deleteFile(path, options) {
545
542
  this.#require('delete');
546
543
  const logicalPath = this.#filePath(path);
547
- assertEtag(options.etag, this.#limits.maxPathBytes, 'Delete');
544
+ assertEtag(options.etag, 'Delete');
548
545
  try {
549
546
  await this.#state.client.deleteConditional(this.#scope(logicalPath), {
550
547
  condition: { etag: options.etag },
@@ -565,14 +562,20 @@ class StorageWorkspaceImplementation {
565
562
  }
566
563
  return new StorageWorkspaceImplementation(WORKSPACE_CONSTRUCTOR, {
567
564
  ...this.#state,
568
- id: `${this.#state.id}/${path}`,
569
565
  prefix: joinWorkspacePath(this.#state.prefix, path),
570
566
  }, resolvePermissions(options.permissions, this.#permissions), resolveLimits(options.limits, this.#limits));
571
567
  }
572
568
  async #copyCreate(sourcePath, destinationPath, options) {
573
569
  try {
574
- const source = await this.#state.client.downloadStream(this.#scope(sourcePath), operationOptions(options));
570
+ const source = await this.#state.client.downloadConditional(this.#scope(sourcePath), {
571
+ condition: { etag: options.etag },
572
+ ...operationOptions(options),
573
+ });
575
574
  this.#assertResultPath(source.key, sourcePath);
575
+ if (source.etag !== options.etag) {
576
+ await source.body.cancel().catch(() => undefined);
577
+ throw workspaceError(StorageErrorCode.PROVIDER, 'Conditional read returned an unexpected source ETag.', { operation: 'copy', path: sourcePath, permanent: true });
578
+ }
576
579
  const bytes = await collectBoundedBytes(source.body, source.size, this.#limits.maxWriteBytes, sourcePath);
577
580
  const result = await this.#state.client.uploadConditional(this.#scope(destinationPath), bytes, {
578
581
  condition: { type: 'create' },
@@ -648,17 +651,19 @@ class StorageWorkspaceImplementation {
648
651
  if (scanned >= this.#limits.maxSearchScan && hasMore) {
649
652
  throw workspaceError(StorageErrorCode.LIMIT_EXCEEDED, `Search exceeded the ${this.#limits.maxSearchScan}-object scan limit.`, { permanent: true });
650
653
  }
654
+ const nextBackendCursor = backendCursor;
651
655
  return {
652
- ...(hasMore && {
653
- cursor: this.#state.cursorStore.issue(context.binding, {
654
- backendCursor,
656
+ ...(nextBackendCursor !== undefined && {
657
+ cursor: await issueStorageWorkspaceCursor(this.#state.cursor, this.#cursorBinding(), {
658
+ backendCursor: nextBackendCursor,
655
659
  caseInsensitive: context.caseInsensitive,
656
660
  directory: context.directory,
657
661
  limit: context.limit,
658
662
  match: context.match,
663
+ operation: 'search',
659
664
  query,
660
665
  scanned,
661
- }, this.#limits.cursorTtlMs),
666
+ }),
662
667
  }),
663
668
  entries,
664
669
  };
@@ -725,8 +730,12 @@ class StorageWorkspaceImplementation {
725
730
  }
726
731
  return limit;
727
732
  }
728
- #binding(operation) {
729
- return `${this.#state.id}:${operation}`;
733
+ #cursorBinding() {
734
+ return {
735
+ limits: this.#limits,
736
+ prefix: this.#state.prefix,
737
+ store: this.#state.client.name,
738
+ };
730
739
  }
731
740
  }
732
741
  export function mountStorageWorkspace(client, options) {
@@ -737,8 +746,7 @@ export function mountStorageWorkspace(client, options) {
737
746
  });
738
747
  return new StorageWorkspaceImplementation(WORKSPACE_CONSTRUCTOR, {
739
748
  client,
740
- cursorStore: new StorageWorkspaceCursorStore(),
741
- id: `workspace:${crypto.randomUUID()}`,
749
+ cursor: resolveStorageWorkspaceCursorConfiguration(options.cursor),
742
750
  prefix,
743
751
  }, resolvePermissions(options.permissions), limits);
744
752
  }
@@ -1 +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 { StorageErrorCode } from '../storage.error.js';\nimport type {\n StorageObjectMetadata,\n StorageOperationOptions,\n StorageUploadResult,\n} from '../storage.types.js';\n\nimport { StorageWorkspaceCursorStore } 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 cursorStore: StorageWorkspaceCursorStore;\n readonly id: string;\n readonly prefix: string;\n}\n\ninterface ListCursorState {\n readonly backendCursor: string;\n readonly directory: string;\n readonly limit: number;\n readonly recursive: boolean;\n}\n\ninterface SearchCursorState {\n readonly backendCursor: string | undefined;\n readonly caseInsensitive: boolean;\n readonly directory: string;\n readonly limit: number;\n readonly match: StorageWorkspaceSearchMatch;\n readonly query: string;\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, maxBytes: number, operation: string): void {\n if (\n typeof etag !== 'string' ||\n etag.length === 0 ||\n containsControlCharacter(etag) ||\n encoder.encode(etag).byteLength > maxBytes\n ) {\n throw workspaceError(\n StorageErrorCode.INVALID_ARGUMENT,\n `${operation} requires a valid non-empty etag.`,\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 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 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 &&\n (typeof metadata.etag !== 'string' || metadata.etag.length === 0)) ||\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 = options.cursor\n ? this.#state.cursorStore.consume<ListCursorState>(\n options.cursor,\n this.#binding('list'),\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 binding = this.#binding('list');\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: this.#state.cursorStore.issue(\n binding,\n {\n backendCursor: page.cursor,\n directory,\n limit,\n recursive,\n } satisfies ListCursorState,\n this.#limits.cursorTtlMs,\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 = options.cursor\n ? this.#state.cursorStore.consume<SearchCursorState>(\n options.cursor,\n this.#binding('search'),\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 binding = this.#binding('search');\n const prior = continuation ?? {\n backendCursor: undefined,\n caseInsensitive,\n directory,\n limit,\n match,\n query,\n scanned: 0,\n };\n return this.#searchPage(query, {\n binding,\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, this.#limits.maxPathBytes, '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?: StorageOperationOptions,\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 if (this.#state.client.capabilities.conditionalMutation?.create !== true) {\n throw workspaceError(\n StorageErrorCode.NOT_SUPPORTED,\n 'Safe copy requires create-only conditional upload support.',\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 conditional = this.#state.client.capabilities.conditionalMutation;\n if (\n conditional?.create !== true ||\n conditional.delete !== true ||\n conditional.etag !== true\n ) {\n throw workspaceError(\n StorageErrorCode.NOT_SUPPORTED,\n 'Safe move requires create-only upload, conditional delete, and upload ETag support.',\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, this.#limits.maxPathBytes, '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, this.#limits.maxPathBytes, '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 id: `${this.#state.id}/${path}`,\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?: StorageOperationOptions,\n ): Promise<StorageWorkspaceFile> {\n try {\n const source = await this.#state.client.downloadStream(\n this.#scope(sourcePath),\n operationOptions(options),\n );\n this.#assertResultPath(source.key, sourcePath);\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 binding: string;\n caseInsensitive: boolean;\n directory: string;\n limit: number;\n match: StorageWorkspaceSearchMatch;\n operation: StorageOperationOptions | undefined;\n state: SearchCursorState;\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 return {\n ...(hasMore && {\n cursor: this.#state.cursorStore.issue(\n context.binding,\n {\n backendCursor,\n caseInsensitive: context.caseInsensitive,\n directory: context.directory,\n limit: context.limit,\n match: context.match,\n query,\n scanned,\n } satisfies SearchCursorState,\n this.#limits.cursorTtlMs,\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 #binding(operation: string): string {\n return `${this.#state.id}:${operation}`;\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 cursorStore: new StorageWorkspaceCursorStore(),\n id: `workspace:${crypto.randomUUID()}`,\n prefix,\n },\n resolvePermissions(options.permissions),\n limits,\n );\n}\n\n/** @deprecated Prefer {@link mountStorageWorkspace}. */\nexport const createStorageWorkspace = mountStorageWorkspace;\n"]}
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"]}
@@ -1,7 +1,10 @@
1
1
  import type { StorageBody, StorageOperationOptions } from '../storage.types.js';
2
+ import type { StorageWorkspaceCursorConfiguration } from './storage-workspace.cursor.js';
2
3
  export declare const STORAGE_WORKSPACE_PERMISSIONS: readonly ['list', 'read', 'search', 'create', 'replace', 'copy', 'move', 'delete'];
3
4
  export type StorageWorkspacePermission = (typeof STORAGE_WORKSPACE_PERMISSIONS)[number];
4
5
  export interface StorageWorkspaceLimits {
6
+ /** Maximum UTF-8 byte length of an opaque continuation cursor. */
7
+ maxCursorBytes: number;
5
8
  /** Maximum UTF-8 byte length of a workspace-relative path. */
6
9
  maxPathBytes: number;
7
10
  /** Maximum bytes returned by a buffered text read. */
@@ -14,7 +17,10 @@ export interface StorageWorkspaceLimits {
14
17
  maxSearchResults: number;
15
18
  /** Maximum objects inspected by one search query across all pages. */
16
19
  maxSearchScan: number;
17
- /** Lifetime of an opaque in-memory continuation cursor. */
20
+ /**
21
+ * Authorization ceiling for an opaque continuation cursor. It does not
22
+ * extend the lifetime or availability of an embedded provider cursor.
23
+ */
18
24
  cursorTtlMs: number;
19
25
  }
20
26
  export declare const DEFAULT_STORAGE_WORKSPACE_LIMITS: Readonly<StorageWorkspaceLimits>;
@@ -47,6 +53,8 @@ export interface StorageWorkspaceMountOptions {
47
53
  export interface MountStorageWorkspaceOptions extends StorageWorkspaceMountOptions {
48
54
  /** Trusted backend namespace. It is never exposed through the workspace. */
49
55
  prefix: string;
56
+ /** Stable server-owned cursor configuration shared across serving replicas. */
57
+ cursor?: StorageWorkspaceCursorConfiguration;
50
58
  }
51
59
  export interface StorageWorkspaceReadOptions extends StorageOperationOptions {
52
60
  maxBytes?: number;
@@ -88,7 +96,7 @@ export interface StorageWorkspace {
88
96
  list(options?: StorageWorkspaceListOptions): Promise<StorageWorkspacePage>;
89
97
  search(query: string, options?: StorageWorkspaceSearchOptions): Promise<StorageWorkspacePage>;
90
98
  writeFile(path: string, body: StorageWorkspaceBody, options: StorageWorkspaceWriteOptions): Promise<StorageWorkspaceFile>;
91
- copyFile(source: string, destination: string, options?: StorageOperationOptions): Promise<StorageWorkspaceFile>;
99
+ copyFile(source: string, destination: string, options: StorageWorkspaceMutationOptions): Promise<StorageWorkspaceFile>;
92
100
  moveFile(source: string, destination: string, options: StorageWorkspaceMutationOptions): Promise<StorageWorkspaceFile>;
93
101
  deleteFile(path: string, options: StorageWorkspaceMutationOptions): Promise<void>;
94
102
  mount(directory: string, options?: StorageWorkspaceMountOptions): StorageWorkspace;