@nestm/storage 0.1.0-alpha.10 → 0.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +153 -0
- package/SECURITY.md +27 -0
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts +37 -0
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts.map +1 -0
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.js +258 -0
- package/dist/ai-sdk/ai-sdk-file-workflow-tools.js.map +1 -0
- package/dist/ai-sdk/index.d.ts +1 -0
- package/dist/ai-sdk/index.d.ts.map +1 -1
- package/dist/ai-sdk/index.js +1 -0
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/bytes/index.d.ts +30 -0
- package/dist/bytes/index.d.ts.map +1 -0
- package/dist/bytes/index.js +96 -0
- package/dist/bytes/index.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/storage-staged-content.d.ts +37 -0
- package/dist/core/storage-staged-content.d.ts.map +1 -0
- package/dist/core/storage-staged-content.js +94 -0
- package/dist/core/storage-staged-content.js.map +1 -0
- package/dist/core/storage-streams.d.ts +19 -0
- package/dist/core/storage-streams.d.ts.map +1 -0
- package/dist/core/storage-streams.js +95 -0
- package/dist/core/storage-streams.js.map +1 -0
- package/dist/core/storage-text.d.ts +33 -0
- package/dist/core/storage-text.d.ts.map +1 -0
- package/dist/core/storage-text.js +98 -0
- package/dist/core/storage-text.js.map +1 -0
- package/dist/files-sdk/memory.d.ts +7 -0
- package/dist/files-sdk/memory.d.ts.map +1 -0
- package/dist/files-sdk/memory.js +72 -0
- package/dist/files-sdk/memory.js.map +1 -0
- package/dist/files-sdk/provider/index.d.ts.map +1 -1
- package/dist/files-sdk/provider/index.js +4 -0
- package/dist/files-sdk/provider/index.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/workspace/index.d.ts +5 -0
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/storage-file-catalog.types.d.ts +65 -0
- package/dist/workspace/storage-file-catalog.types.d.ts.map +1 -0
- package/dist/workspace/storage-file-catalog.types.js +2 -0
- package/dist/workspace/storage-file-catalog.types.js.map +1 -0
- package/dist/workspace/storage-file-workflow.d.ts +7 -0
- package/dist/workspace/storage-file-workflow.d.ts.map +1 -0
- package/dist/workspace/storage-file-workflow.js +440 -0
- package/dist/workspace/storage-file-workflow.js.map +1 -0
- package/dist/workspace/storage-file-workflow.protection.d.ts +31 -0
- package/dist/workspace/storage-file-workflow.protection.d.ts.map +1 -0
- package/dist/workspace/storage-file-workflow.protection.js +258 -0
- package/dist/workspace/storage-file-workflow.protection.js.map +1 -0
- package/dist/workspace/storage-file-workflow.types.d.ts +128 -0
- package/dist/workspace/storage-file-workflow.types.d.ts.map +1 -0
- package/dist/workspace/storage-file-workflow.types.js +8 -0
- package/dist/workspace/storage-file-workflow.types.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createStoredFile, FilesError, } from 'files-sdk';
|
|
2
|
+
import { memory } from 'files-sdk/memory';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
const decorated = new WeakSet();
|
|
5
|
+
/**
|
|
6
|
+
* Reuses files-sdk buffering/metadata; comparisons and Map replacement share a
|
|
7
|
+
* synchronous linearization point AFTER body consumption. raw stays host-only.
|
|
8
|
+
*/
|
|
9
|
+
export function withMemoryConditionalOperations(adapter) {
|
|
10
|
+
if (decorated.has(adapter))
|
|
11
|
+
return adapter;
|
|
12
|
+
decorated.add(adapter);
|
|
13
|
+
// Upstream memory uses a quoted 32-bit content checksum. Give every publication
|
|
14
|
+
// (ordinary, copy, resumable or conditional) a canonical SHA-256 identity at
|
|
15
|
+
// the Map's synchronous set boundary; uploads return this same entry object.
|
|
16
|
+
const set = adapter.raw.set.bind(adapter.raw);
|
|
17
|
+
Object.defineProperty(adapter.raw, 'set', {
|
|
18
|
+
value: (key, entry) => {
|
|
19
|
+
entry.etag = createHash('sha256').update(entry.bytes).digest('hex');
|
|
20
|
+
return set(key, entry);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
for (const [key, entry] of adapter.raw)
|
|
24
|
+
adapter.raw.set(key, entry);
|
|
25
|
+
const upload = async (key, body, expectedEtag, options) => {
|
|
26
|
+
options?.signal?.throwIfAborted();
|
|
27
|
+
// An isolated upstream store performs its usual body conversion and hashing.
|
|
28
|
+
const staged = memory();
|
|
29
|
+
const result = await staged.upload(key, body, options);
|
|
30
|
+
options?.signal?.throwIfAborted();
|
|
31
|
+
const current = adapter.raw.get(key);
|
|
32
|
+
if (expectedEtag === null
|
|
33
|
+
? current !== undefined
|
|
34
|
+
: current?.etag !== expectedEtag)
|
|
35
|
+
throw new FilesError('Conflict', 'Memory object condition did not match.');
|
|
36
|
+
// No await/callback between the comparison and publication, including when
|
|
37
|
+
// ordinary upstream writes race this conditional operation.
|
|
38
|
+
adapter.raw.set(key, staged.raw.get(key));
|
|
39
|
+
return { ...result, etag: staged.raw.get(key).etag };
|
|
40
|
+
};
|
|
41
|
+
const conditional = {
|
|
42
|
+
create: (key, body, options) => upload(key, body, null, options),
|
|
43
|
+
replace: (key, body, etag, options) => upload(key, body, etag, options),
|
|
44
|
+
exactRead: async (key, etag, options) => {
|
|
45
|
+
options?.signal?.throwIfAborted();
|
|
46
|
+
const entry = adapter.raw.get(key);
|
|
47
|
+
if (entry === undefined || entry.etag !== etag)
|
|
48
|
+
throw new FilesError('Conflict', 'Memory object condition did not match.');
|
|
49
|
+
const range = options?.range;
|
|
50
|
+
const bytes = entry.bytes.slice(range?.start ?? 0, range?.end === undefined ? undefined : range.end + 1);
|
|
51
|
+
return createStoredFile({
|
|
52
|
+
key,
|
|
53
|
+
etag: entry.etag,
|
|
54
|
+
size: bytes.byteLength,
|
|
55
|
+
type: entry.contentType,
|
|
56
|
+
lastModified: entry.lastModified,
|
|
57
|
+
...(entry.metadata === undefined
|
|
58
|
+
? {}
|
|
59
|
+
: { metadata: { ...entry.metadata } }),
|
|
60
|
+
}, { kind: 'buffer', data: bytes });
|
|
61
|
+
},
|
|
62
|
+
delete: async (key, etag, options) => {
|
|
63
|
+
options?.signal?.throwIfAborted();
|
|
64
|
+
const entry = adapter.raw.get(key);
|
|
65
|
+
if (entry === undefined || entry.etag !== etag)
|
|
66
|
+
throw new FilesError('Conflict', 'Memory object condition did not match.');
|
|
67
|
+
adapter.raw.delete(key);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return Object.assign(adapter, { conditional: Object.freeze(conditional) });
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/files-sdk/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createStoredFile,\n FilesError,\n type AdapterConditionalOperations,\n type AdapterUploadOptions,\n type Body,\n} from 'files-sdk';\nimport { memory, type MemoryAdapter, type MemoryEntry } from 'files-sdk/memory';\nimport { createHash } from 'node:crypto';\n\nconst decorated = new WeakSet<MemoryAdapter>();\n\n/**\n * Reuses files-sdk buffering/metadata; comparisons and Map replacement share a\n * synchronous linearization point AFTER body consumption. raw stays host-only.\n */\nexport function withMemoryConditionalOperations(\n adapter: MemoryAdapter,\n): MemoryAdapter {\n if (decorated.has(adapter)) return adapter;\n decorated.add(adapter);\n // Upstream memory uses a quoted 32-bit content checksum. Give every publication\n // (ordinary, copy, resumable or conditional) a canonical SHA-256 identity at\n // the Map's synchronous set boundary; uploads return this same entry object.\n const set = adapter.raw.set.bind(adapter.raw);\n Object.defineProperty(adapter.raw, 'set', {\n value: (key: string, entry: MemoryEntry) => {\n entry.etag = createHash('sha256').update(entry.bytes).digest('hex');\n return set(key, entry);\n },\n });\n for (const [key, entry] of adapter.raw) adapter.raw.set(key, entry);\n const upload = async (\n key: string,\n body: Body,\n expectedEtag: string | null,\n options?: AdapterUploadOptions,\n ) => {\n options?.signal?.throwIfAborted();\n // An isolated upstream store performs its usual body conversion and hashing.\n const staged = memory();\n const result = await staged.upload(key, body, options);\n options?.signal?.throwIfAborted();\n const current = adapter.raw.get(key);\n if (\n expectedEtag === null\n ? current !== undefined\n : current?.etag !== expectedEtag\n )\n throw new FilesError(\n 'Conflict',\n 'Memory object condition did not match.',\n );\n // No await/callback between the comparison and publication, including when\n // ordinary upstream writes race this conditional operation.\n adapter.raw.set(key, staged.raw.get(key)!);\n return { ...result, etag: staged.raw.get(key)!.etag };\n };\n const conditional: AdapterConditionalOperations = {\n create: (key, body, options) => upload(key, body, null, options),\n replace: (key, body, etag, options) => upload(key, body, etag, options),\n exactRead: async (key, etag, options) => {\n options?.signal?.throwIfAborted();\n const entry = adapter.raw.get(key);\n if (entry === undefined || entry.etag !== etag)\n throw new FilesError(\n 'Conflict',\n 'Memory object condition did not match.',\n );\n const range = options?.range;\n const bytes = entry.bytes.slice(\n range?.start ?? 0,\n range?.end === undefined ? undefined : range.end + 1,\n );\n return createStoredFile(\n {\n key,\n etag: entry.etag,\n size: bytes.byteLength,\n type: entry.contentType,\n lastModified: entry.lastModified,\n ...(entry.metadata === undefined\n ? {}\n : { metadata: { ...entry.metadata } }),\n },\n { kind: 'buffer', data: bytes },\n );\n },\n delete: async (key, etag, options) => {\n options?.signal?.throwIfAborted();\n const entry = adapter.raw.get(key);\n if (entry === undefined || entry.etag !== etag)\n throw new FilesError(\n 'Conflict',\n 'Memory object condition did not match.',\n );\n adapter.raw.delete(key);\n },\n };\n return Object.assign(adapter, { conditional: Object.freeze(conditional) });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/files-sdk/provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAKL,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMnE,sEAAsE;AACtE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AAEvE,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,qBAAqB,CAAC,OAAO,CAAC,EAC9B,SAAS,CACV;IACC,wFAAwF;IACxF,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,qBAAqB,CAAC,CAoBhC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/files-sdk/provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAKL,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMnE,sEAAsE;AACtE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AAEvE,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,qBAAqB,CAAC,OAAO,CAAC,EAC9B,SAAS,CACV;IACC,wFAAwF;IACxF,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,qBAAqB,CAAC,CAoBhC;AA2HD,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,mBAAmB,CAE7E;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,IAAI,SAAS,QAAQ,EAAE,CAE1D;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAErE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjE;AAED,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE;AAED,YAAY,EACV,MAAM,IAAI,qBAAqB,EAC/B,QAAQ,IAAI,mBAAmB,GAChC,MAAM,qBAAqB,CAAC"}
|
|
@@ -62,6 +62,10 @@ async function resolveAdapter(provider, config, s3ProviderProfile) {
|
|
|
62
62
|
throw mapFilesSdkError(error);
|
|
63
63
|
}
|
|
64
64
|
const { adapter } = resolved.files;
|
|
65
|
+
if (provider === 'memory') {
|
|
66
|
+
const { withMemoryConditionalOperations } = await import('../memory.js');
|
|
67
|
+
return withMemoryConditionalOperations(adapter);
|
|
68
|
+
}
|
|
65
69
|
if (provider === 'fs') {
|
|
66
70
|
const { withFsConditionalMutation } = await import('../fs/index.js');
|
|
67
71
|
return withFsConditionalMutation(adapter);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/files-sdk/provider/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapter } from 'files-sdk';\nimport { loadFiles, type LoadFilesOptions } from 'files-sdk/loader';\nimport {\n PROVIDER_NAMES,\n getProvider,\n getSecretEnvVars,\n listEnvVars,\n type EnvVar,\n type Provider,\n type ProviderSlug,\n} from 'files-sdk/providers';\n\nimport { StorageError, StorageErrorCode } from '../../storage.error.js';\nimport {\n createFilesSdkDriver,\n mapFilesSdkError,\n type FilesSdkDriverOptions,\n type FilesSdkStorageDriver,\n} from '../files-sdk.driver.js';\nimport type { S3Adapter, S3ProviderProfile } from '../s3/index.js';\nimport {\n recordS3ConditionalRequestPermission,\n recordS3ConstructionMetadata,\n} from '../s3/construction-metadata.js';\n\n/** Slug of a storage provider this package can build a driver for. */\nexport type StorageProviderName = ProviderSlug;\n\n/**\n * Flat, provider-specific settings — `bucket` and `region` for an object store,\n * `root` for the filesystem, `accountName` and `container` for Azure, and so\n * on. Every provider reads what it needs and ignores the rest, so one config\n * shape serves a deployment that switches providers by name.\n *\n * Credentials may be omitted for any provider whose SDK resolves its own chain\n * (an IAM role, Application Default Credentials, a shared profile).\n */\nexport type StorageProviderConfig = Omit<LoadFilesOptions, 'provider'>;\n\nexport interface ProviderStorageDriverOptions extends Omit<\n FilesSdkDriverOptions<Adapter>,\n 'adapter'\n> {\n /** Which provider to build. Validate untrusted input with {@link isStorageProvider}. */\n provider: StorageProviderName;\n config?: StorageProviderConfig;\n /** Verified operation profile for the `s3` slug, especially custom endpoints. */\n s3ProviderProfile?: S3ProviderProfile;\n}\n\n/**\n * Builds a {@link FilesSdkStorageDriver} for a provider named at runtime,\n * importing that provider's adapter — and only that one — on demand. A\n * deployment selects its store with a string (`'s3'`, `'gcs'`, `'azure'`,\n * `'r2'`, `'fs'`, …) and installs one native SDK, instead of the application\n * hard-coding a driver per backend.\n *\n * The `s3` slug additionally gets the exact verified provider profile and\n * signed-policy capabilities {@link createS3StorageDriver} attaches. Providers\n * not backed by the AWS S3 SDK expose what their adapter declares;\n * noncanonical S3-backed providers default to an unverified, read-only profile.\n * Import `@nestm/storage/files-sdk/s3` directly when the provider is known at\n * build time and the extra indirection buys nothing.\n *\n * @throws StorageError `INVALID_ARGUMENT` for an unknown slug, and whatever the\n * adapter reports (mapped) when required config or credentials are missing.\n */\nexport async function createProviderStorageDriver(\n options: ProviderStorageDriverOptions,\n): Promise<FilesSdkStorageDriver> {\n const { provider, config, s3ProviderProfile, ...filesOptions } = options;\n if (!isStorageProvider(provider)) {\n throw unknownProvider(provider);\n }\n\n // `loadFiles` owns the slug → adapter mapping and keeps the import lazy; the\n // client it returns is discarded so the caller's own driver options (prefix,\n // hooks, plugins, readonly, retries) apply to the instance the bridge builds.\n if (s3ProviderProfile !== undefined && provider !== 's3') {\n throw new StorageError(\n 's3ProviderProfile can only be used with the \"s3\" provider.',\n { code: StorageErrorCode.INVALID_ARGUMENT, permanent: true },\n );\n }\n const adapter = await resolveAdapter(provider, config, s3ProviderProfile);\n return createFilesSdkDriver({\n ...filesOptions,\n adapter,\n });\n}\n\nfunction isS3BackedAdapter(adapter: Adapter): adapter is S3Adapter {\n try {\n const raw = adapter.raw;\n if (typeof raw !== 'object' || raw === null) return false;\n const candidate = raw as {\n readonly config?: unknown;\n readonly send?: unknown;\n };\n return (\n typeof candidate.send === 'function' &&\n typeof candidate.config === 'object' &&\n candidate.config !== null &&\n (candidate.config as { readonly serviceId?: unknown }).serviceId === 'S3'\n );\n } catch {\n return false;\n }\n}\n\nasync function resolveAdapter(\n provider: StorageProviderName,\n config: StorageProviderConfig | undefined,\n s3ProviderProfile: S3ProviderProfile | undefined,\n): Promise<Adapter> {\n const loaderConfig = withVerifiedS3ConditionalOptIn(\n provider,\n config,\n s3ProviderProfile,\n );\n let resolved;\n try {\n resolved = await loadFiles({ ...loaderConfig, provider });\n } catch (error) {\n throw mapFilesSdkError(error);\n }\n const { adapter } = resolved.files;\n if (provider === 'fs') {\n const { withFsConditionalMutation } = await import('../fs/index.js');\n return withFsConditionalMutation(\n adapter as Parameters<typeof withFsConditionalMutation>[0],\n );\n }\n if (!isS3BackedAdapter(adapter)) {\n return adapter;\n }\n // Every AWS-SDK-backed wrapper gets fail-closed S3 provenance and endpoint\n // hardening. Only the canonical `s3` slug may infer native AWS or accept an\n // explicit verified profile; named compatibles remain unverified/read-only.\n const { withS3Capabilities } = await import('../s3/index.js');\n const configJsonPublicBaseUrl = config?.configJson?.publicBaseUrl;\n const publicBaseUrl =\n config?.publicBaseUrl ??\n (typeof configJsonPublicBaseUrl === 'string'\n ? configJsonPublicBaseUrl\n : undefined);\n const s3Adapter = adapter as Parameters<typeof withS3Capabilities>[0];\n if (provider === 's3') {\n recordS3ConditionalRequestPermission(\n s3Adapter.raw,\n config?.configJson?.conditional !== false,\n );\n }\n recordS3ConstructionMetadata(s3Adapter.raw, {\n publicBaseUrlConfigured:\n provider !== 's3' ||\n config?.publicBaseUrl !== undefined ||\n configJsonPublicBaseUrl !== undefined,\n });\n return withS3Capabilities(s3Adapter, {\n ...(typeof config?.endpoint === 'string' && {\n endpoint: config.endpoint,\n }),\n ...(publicBaseUrl !== undefined && {\n publicBaseUrl,\n }),\n ...(s3ProviderProfile !== undefined && {\n providerProfile: s3ProviderProfile,\n }),\n });\n}\n\nfunction withVerifiedS3ConditionalOptIn(\n provider: StorageProviderName,\n config: StorageProviderConfig | undefined,\n s3ProviderProfile: S3ProviderProfile | undefined,\n): StorageProviderConfig | undefined {\n const configJsonEndpoint = config?.configJson?.endpoint;\n const hasCustomEndpoint =\n config?.endpoint !== undefined || configJsonEndpoint !== undefined;\n if (\n provider !== 's3' ||\n s3ProviderProfile === undefined ||\n config === undefined ||\n !hasCustomEndpoint ||\n config.configJson?.conditional !== undefined\n ) {\n return config;\n }\n\n // files-sdk requires this construction-time opt-in before it exposes native\n // conditional primitives for a custom endpoint. The branded provider profile\n // still narrows the exposed operations in withS3Capabilities below.\n return {\n ...config,\n configJson: { ...config.configJson, conditional: true },\n };\n}\n\nfunction unknownProvider(provider: string): StorageError {\n return new StorageError(\n `Unknown storage provider: ${JSON.stringify(provider)}. Known providers: ${PROVIDER_NAMES.join(', ')}.`,\n { code: StorageErrorCode.INVALID_ARGUMENT, permanent: true },\n );\n}\n\n/** Narrows an untrusted string — an env var, a config file — to a known slug. */\nexport function isStorageProvider(value: string): value is StorageProviderName {\n return getProvider(value) !== undefined;\n}\n\n/** Every provider that can be named, sorted by slug. */\nexport function listStorageProviders(): readonly Provider[] {\n return PROVIDER_NAMES.flatMap((slug) => getProvider(slug) ?? []);\n}\n\n/** One provider's display name, description, native SDKs, and env contract. */\nexport function getStorageProvider(slug: string): Provider | undefined {\n return getProvider(slug);\n}\n\n/**\n * Every environment variable a provider reads, flattened across required, all\n * credential modes, and optional. Useful for validating a deployment's config\n * before the first upload rather than at it.\n */\nexport function listStorageProviderEnvVars(slug: string): EnvVar[] {\n return listEnvVars(slug);\n}\n\n/** The subset of {@link listStorageProviderEnvVars} that carries secrets. */\nexport function listStorageProviderSecretEnvVars(slug: string): EnvVar[] {\n return getSecretEnvVars(slug);\n}\n\nexport type {\n EnvVar as StorageProviderEnvVar,\n Provider as StorageProviderInfo,\n} from 'files-sdk/providers';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/files-sdk/provider/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Adapter } from 'files-sdk';\nimport { loadFiles, type LoadFilesOptions } from 'files-sdk/loader';\nimport {\n PROVIDER_NAMES,\n getProvider,\n getSecretEnvVars,\n listEnvVars,\n type EnvVar,\n type Provider,\n type ProviderSlug,\n} from 'files-sdk/providers';\n\nimport { StorageError, StorageErrorCode } from '../../storage.error.js';\nimport {\n createFilesSdkDriver,\n mapFilesSdkError,\n type FilesSdkDriverOptions,\n type FilesSdkStorageDriver,\n} from '../files-sdk.driver.js';\nimport type { S3Adapter, S3ProviderProfile } from '../s3/index.js';\nimport {\n recordS3ConditionalRequestPermission,\n recordS3ConstructionMetadata,\n} from '../s3/construction-metadata.js';\n\n/** Slug of a storage provider this package can build a driver for. */\nexport type StorageProviderName = ProviderSlug;\n\n/**\n * Flat, provider-specific settings — `bucket` and `region` for an object store,\n * `root` for the filesystem, `accountName` and `container` for Azure, and so\n * on. Every provider reads what it needs and ignores the rest, so one config\n * shape serves a deployment that switches providers by name.\n *\n * Credentials may be omitted for any provider whose SDK resolves its own chain\n * (an IAM role, Application Default Credentials, a shared profile).\n */\nexport type StorageProviderConfig = Omit<LoadFilesOptions, 'provider'>;\n\nexport interface ProviderStorageDriverOptions extends Omit<\n FilesSdkDriverOptions<Adapter>,\n 'adapter'\n> {\n /** Which provider to build. Validate untrusted input with {@link isStorageProvider}. */\n provider: StorageProviderName;\n config?: StorageProviderConfig;\n /** Verified operation profile for the `s3` slug, especially custom endpoints. */\n s3ProviderProfile?: S3ProviderProfile;\n}\n\n/**\n * Builds a {@link FilesSdkStorageDriver} for a provider named at runtime,\n * importing that provider's adapter — and only that one — on demand. A\n * deployment selects its store with a string (`'s3'`, `'gcs'`, `'azure'`,\n * `'r2'`, `'fs'`, …) and installs one native SDK, instead of the application\n * hard-coding a driver per backend.\n *\n * The `s3` slug additionally gets the exact verified provider profile and\n * signed-policy capabilities {@link createS3StorageDriver} attaches. Providers\n * not backed by the AWS S3 SDK expose what their adapter declares;\n * noncanonical S3-backed providers default to an unverified, read-only profile.\n * Import `@nestm/storage/files-sdk/s3` directly when the provider is known at\n * build time and the extra indirection buys nothing.\n *\n * @throws StorageError `INVALID_ARGUMENT` for an unknown slug, and whatever the\n * adapter reports (mapped) when required config or credentials are missing.\n */\nexport async function createProviderStorageDriver(\n options: ProviderStorageDriverOptions,\n): Promise<FilesSdkStorageDriver> {\n const { provider, config, s3ProviderProfile, ...filesOptions } = options;\n if (!isStorageProvider(provider)) {\n throw unknownProvider(provider);\n }\n\n // `loadFiles` owns the slug → adapter mapping and keeps the import lazy; the\n // client it returns is discarded so the caller's own driver options (prefix,\n // hooks, plugins, readonly, retries) apply to the instance the bridge builds.\n if (s3ProviderProfile !== undefined && provider !== 's3') {\n throw new StorageError(\n 's3ProviderProfile can only be used with the \"s3\" provider.',\n { code: StorageErrorCode.INVALID_ARGUMENT, permanent: true },\n );\n }\n const adapter = await resolveAdapter(provider, config, s3ProviderProfile);\n return createFilesSdkDriver({\n ...filesOptions,\n adapter,\n });\n}\n\nfunction isS3BackedAdapter(adapter: Adapter): adapter is S3Adapter {\n try {\n const raw = adapter.raw;\n if (typeof raw !== 'object' || raw === null) return false;\n const candidate = raw as {\n readonly config?: unknown;\n readonly send?: unknown;\n };\n return (\n typeof candidate.send === 'function' &&\n typeof candidate.config === 'object' &&\n candidate.config !== null &&\n (candidate.config as { readonly serviceId?: unknown }).serviceId === 'S3'\n );\n } catch {\n return false;\n }\n}\n\nasync function resolveAdapter(\n provider: StorageProviderName,\n config: StorageProviderConfig | undefined,\n s3ProviderProfile: S3ProviderProfile | undefined,\n): Promise<Adapter> {\n const loaderConfig = withVerifiedS3ConditionalOptIn(\n provider,\n config,\n s3ProviderProfile,\n );\n let resolved;\n try {\n resolved = await loadFiles({ ...loaderConfig, provider });\n } catch (error) {\n throw mapFilesSdkError(error);\n }\n const { adapter } = resolved.files;\n if (provider === 'memory') {\n const { withMemoryConditionalOperations } = await import('../memory.js');\n return withMemoryConditionalOperations(\n adapter as Parameters<typeof withMemoryConditionalOperations>[0],\n );\n }\n if (provider === 'fs') {\n const { withFsConditionalMutation } = await import('../fs/index.js');\n return withFsConditionalMutation(\n adapter as Parameters<typeof withFsConditionalMutation>[0],\n );\n }\n if (!isS3BackedAdapter(adapter)) {\n return adapter;\n }\n // Every AWS-SDK-backed wrapper gets fail-closed S3 provenance and endpoint\n // hardening. Only the canonical `s3` slug may infer native AWS or accept an\n // explicit verified profile; named compatibles remain unverified/read-only.\n const { withS3Capabilities } = await import('../s3/index.js');\n const configJsonPublicBaseUrl = config?.configJson?.publicBaseUrl;\n const publicBaseUrl =\n config?.publicBaseUrl ??\n (typeof configJsonPublicBaseUrl === 'string'\n ? configJsonPublicBaseUrl\n : undefined);\n const s3Adapter = adapter as Parameters<typeof withS3Capabilities>[0];\n if (provider === 's3') {\n recordS3ConditionalRequestPermission(\n s3Adapter.raw,\n config?.configJson?.conditional !== false,\n );\n }\n recordS3ConstructionMetadata(s3Adapter.raw, {\n publicBaseUrlConfigured:\n provider !== 's3' ||\n config?.publicBaseUrl !== undefined ||\n configJsonPublicBaseUrl !== undefined,\n });\n return withS3Capabilities(s3Adapter, {\n ...(typeof config?.endpoint === 'string' && {\n endpoint: config.endpoint,\n }),\n ...(publicBaseUrl !== undefined && {\n publicBaseUrl,\n }),\n ...(s3ProviderProfile !== undefined && {\n providerProfile: s3ProviderProfile,\n }),\n });\n}\n\nfunction withVerifiedS3ConditionalOptIn(\n provider: StorageProviderName,\n config: StorageProviderConfig | undefined,\n s3ProviderProfile: S3ProviderProfile | undefined,\n): StorageProviderConfig | undefined {\n const configJsonEndpoint = config?.configJson?.endpoint;\n const hasCustomEndpoint =\n config?.endpoint !== undefined || configJsonEndpoint !== undefined;\n if (\n provider !== 's3' ||\n s3ProviderProfile === undefined ||\n config === undefined ||\n !hasCustomEndpoint ||\n config.configJson?.conditional !== undefined\n ) {\n return config;\n }\n\n // files-sdk requires this construction-time opt-in before it exposes native\n // conditional primitives for a custom endpoint. The branded provider profile\n // still narrows the exposed operations in withS3Capabilities below.\n return {\n ...config,\n configJson: { ...config.configJson, conditional: true },\n };\n}\n\nfunction unknownProvider(provider: string): StorageError {\n return new StorageError(\n `Unknown storage provider: ${JSON.stringify(provider)}. Known providers: ${PROVIDER_NAMES.join(', ')}.`,\n { code: StorageErrorCode.INVALID_ARGUMENT, permanent: true },\n );\n}\n\n/** Narrows an untrusted string — an env var, a config file — to a known slug. */\nexport function isStorageProvider(value: string): value is StorageProviderName {\n return getProvider(value) !== undefined;\n}\n\n/** Every provider that can be named, sorted by slug. */\nexport function listStorageProviders(): readonly Provider[] {\n return PROVIDER_NAMES.flatMap((slug) => getProvider(slug) ?? []);\n}\n\n/** One provider's display name, description, native SDKs, and env contract. */\nexport function getStorageProvider(slug: string): Provider | undefined {\n return getProvider(slug);\n}\n\n/**\n * Every environment variable a provider reads, flattened across required, all\n * credential modes, and optional. Useful for validating a deployment's config\n * before the first upload rather than at it.\n */\nexport function listStorageProviderEnvVars(slug: string): EnvVar[] {\n return listEnvVars(slug);\n}\n\n/** The subset of {@link listStorageProviderEnvVars} that carries secrets. */\nexport function listStorageProviderSecretEnvVars(slug: string): EnvVar[] {\n return getSecretEnvVars(slug);\n}\n\nexport type {\n EnvVar as StorageProviderEnvVar,\n Provider as StorageProviderInfo,\n} from 'files-sdk/providers';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,qBAAqB,CAAC,aAAa,CAAC,EACpC,SAAS,CACV;IACC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,aAAa,CAMf;AAED,OAAO,EACL,qCAAqC,EACrC,KAAK,sCAAsC,EAC3C,KAAK,8BAA8B,EACnC,KAAK,oCAAoC,EACzC,KAAK,iCAAiC,EACtC,KAAK,iCAAiC,GACvC,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/testing/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { withMemoryConditionalOperations } from '../files-sdk/memory.js';
|
|
1
2
|
import { createFilesSdkDriver, } from '../files-sdk/files-sdk.driver.js';
|
|
2
3
|
import { memory, } from 'files-sdk/memory';
|
|
3
4
|
export function createMemoryStorageDriver(options = {}) {
|
|
4
5
|
const { adapter, ...filesOptions } = options;
|
|
5
6
|
return createFilesSdkDriver({
|
|
6
7
|
...filesOptions,
|
|
7
|
-
adapter: memory(adapter),
|
|
8
|
+
adapter: withMemoryConditionalOperations(memory(adapter)),
|
|
8
9
|
});
|
|
9
10
|
}
|
|
10
11
|
export { createStorageProviderConformanceCases, } from './provider-conformance.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,GAErB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,MAAM,GAGP,MAAM,kBAAkB,CAAC;AAS1B,MAAM,UAAU,yBAAyB,CACvC,OAAO,GAA+B,EAAE;IAExC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;IAC7C,OAAO,oBAAoB,CAAC;QAC1B,GAAG,YAAY;QACf,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EACL,oBAAoB,GAErB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,MAAM,GAGP,MAAM,kBAAkB,CAAC;AAS1B,MAAM,UAAU,yBAAyB,CACvC,OAAO,GAA+B,EAAE;IAExC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;IAC7C,OAAO,oBAAoB,CAAC;QAC1B,GAAG,YAAY;QACf,OAAO,EAAE,+BAA+B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EACL,qCAAqC,GAMtC,MAAM,2BAA2B,CAAC","sourcesContent":["import type { StorageDriver } from '../storage.driver.js';\nimport { withMemoryConditionalOperations } from '../files-sdk/memory.js';\nimport {\n createFilesSdkDriver,\n type FilesSdkDriverOptions,\n} from '../files-sdk/files-sdk.driver.js';\nimport {\n memory,\n type MemoryAdapter,\n type MemoryAdapterOptions,\n} from 'files-sdk/memory';\n\nexport interface MemoryStorageDriverOptions extends Omit<\n FilesSdkDriverOptions<MemoryAdapter>,\n 'adapter'\n> {\n adapter?: MemoryAdapterOptions;\n}\n\nexport function createMemoryStorageDriver(\n options: MemoryStorageDriverOptions = {},\n): StorageDriver {\n const { adapter, ...filesOptions } = options;\n return createFilesSdkDriver({\n ...filesOptions,\n adapter: withMemoryConditionalOperations(memory(adapter)),\n });\n}\n\nexport {\n createStorageProviderConformanceCases,\n type StorageProviderConformanceCapabilities,\n type StorageProviderConformanceCase,\n type StorageProviderConformanceCaseResult,\n type StorageProviderConformanceFixture,\n type StorageProviderConformanceOptions,\n} from './provider-conformance.js';\n\nexport type { MemoryAdapterOptions, MemorySeed } from 'files-sdk/memory';\n"]}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export { StorageWorkspaceError, isStorageWorkspaceError, } from './storage-workspace.error.js';
|
|
2
|
+
export { StorageFileWorkflow } from './storage-file-workflow.js';
|
|
3
|
+
export { DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS } from './storage-file-workflow.types.js';
|
|
4
|
+
export type * from './storage-file-workflow.types.js';
|
|
5
|
+
export type * from './storage-file-catalog.types.js';
|
|
6
|
+
export { protectStorageFileWorkflowWorkspace, protectStorageFileWorkflowOperation, getStorageFileWorkflow, getStorageFileCatalog, type StorageFileWorkflowProtection, type StorageFileWorkflowWorkspace, type ProtectStorageFileWorkflowWorkspaceOptions, } from './storage-file-workflow.protection.js';
|
|
2
7
|
export { Aes256GcmStorageWorkspaceCursorCodec, STORAGE_WORKSPACE_CURSOR_VERSION, STORAGE_WORKSPACE_MAX_CURSOR_BYTES, type Aes256GcmStorageWorkspaceCursorCodecOptions, type StorageWorkspaceCursorCodec, type StorageWorkspaceCursorConfiguration, type StorageWorkspaceCursorEncodeOptions, } from './storage-workspace.cursor.js';
|
|
3
8
|
export { createStorageWorkspace, mountStorageWorkspace, } from './storage-workspace.js';
|
|
4
9
|
export { DEFAULT_STORAGE_WORKSPACE_LIMITS, STORAGE_WORKSPACE_PERMISSIONS, type MountStorageWorkspaceOptions, type StorageWorkspaceBody, type StorageWorkspaceByteFile, type StorageWorkspaceCopyOptions, type StorageWorkspaceDeleteOptions, type StorageWorkspace, type StorageWorkspaceDirectory, type StorageWorkspaceEntry, type StorageWorkspaceFile, type StorageWorkspaceLimits, type StorageWorkspaceListOptions, type StorageWorkspaceMountOptions, type StorageWorkspaceMutationOptions, type StorageWorkspaceOverwriteOptions, type StorageWorkspacePage, type StorageWorkspacePermission, type StorageWorkspaceReadOptions, type StorageWorkspaceSearchMatch, type StorageWorkspaceSearchOptions, type StorageWorkspaceTextFile, type StorageWorkspaceUnconditionalDeleteOptions, type StorageWorkspaceWriteOptions, } from './storage-workspace.types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,EAClC,KAAK,2CAA2C,EAChD,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,mCAAmC,GACzC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,0CAA0C,EAC/C,KAAK,4BAA4B,GAClC,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AACxF,mBAAmB,kCAAkC,CAAC;AACtD,mBAAmB,iCAAiC,CAAC;AACrD,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,0CAA0C,GAChD,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,EAClC,KAAK,2CAA2C,EAChD,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,mCAAmC,GACzC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,0CAA0C,EAC/C,KAAK,4BAA4B,GAClC,MAAM,8BAA8B,CAAC"}
|
package/dist/workspace/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { StorageWorkspaceError, isStorageWorkspaceError, } from './storage-workspace.error.js';
|
|
2
|
+
export { StorageFileWorkflow } from './storage-file-workflow.js';
|
|
3
|
+
export { DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS } from './storage-file-workflow.types.js';
|
|
4
|
+
export { protectStorageFileWorkflowWorkspace, protectStorageFileWorkflowOperation, getStorageFileWorkflow, getStorageFileCatalog, } from './storage-file-workflow.protection.js';
|
|
2
5
|
export { Aes256GcmStorageWorkspaceCursorCodec, STORAGE_WORKSPACE_CURSOR_VERSION, STORAGE_WORKSPACE_MAX_CURSOR_BYTES, } from './storage-workspace.cursor.js';
|
|
3
6
|
export { createStorageWorkspace, mountStorageWorkspace, } from './storage-workspace.js';
|
|
4
7
|
export { DEFAULT_STORAGE_WORKSPACE_LIMITS, STORAGE_WORKSPACE_PERMISSIONS, } from './storage-workspace.types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,GAKnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAuB9B,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n StorageWorkspaceError,\n isStorageWorkspaceError,\n} from './storage-workspace.error.js';\nexport {\n Aes256GcmStorageWorkspaceCursorCodec,\n STORAGE_WORKSPACE_CURSOR_VERSION,\n STORAGE_WORKSPACE_MAX_CURSOR_BYTES,\n type Aes256GcmStorageWorkspaceCursorCodecOptions,\n type StorageWorkspaceCursorCodec,\n type StorageWorkspaceCursorConfiguration,\n type StorageWorkspaceCursorEncodeOptions,\n} from './storage-workspace.cursor.js';\nexport {\n createStorageWorkspace,\n mountStorageWorkspace,\n} from './storage-workspace.js';\nexport {\n DEFAULT_STORAGE_WORKSPACE_LIMITS,\n STORAGE_WORKSPACE_PERMISSIONS,\n type MountStorageWorkspaceOptions,\n type StorageWorkspaceBody,\n type StorageWorkspaceByteFile,\n type StorageWorkspaceCopyOptions,\n type StorageWorkspaceDeleteOptions,\n type StorageWorkspace,\n type StorageWorkspaceDirectory,\n type StorageWorkspaceEntry,\n type StorageWorkspaceFile,\n type StorageWorkspaceLimits,\n type StorageWorkspaceListOptions,\n type StorageWorkspaceMountOptions,\n type StorageWorkspaceMutationOptions,\n type StorageWorkspaceOverwriteOptions,\n type StorageWorkspacePage,\n type StorageWorkspacePermission,\n type StorageWorkspaceReadOptions,\n type StorageWorkspaceSearchMatch,\n type StorageWorkspaceSearchOptions,\n type StorageWorkspaceTextFile,\n type StorageWorkspaceUnconditionalDeleteOptions,\n type StorageWorkspaceWriteOptions,\n} from './storage-workspace.types.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oCAAoC,EAAE,MAAM,kCAAkC,CAAC;AAGxF,OAAO,EACL,mCAAmC,EACnC,mCAAmC,EACnC,sBAAsB,EACtB,qBAAqB,GAItB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,oCAAoC,EACpC,gCAAgC,EAChC,kCAAkC,GAKnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAuB9B,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n StorageWorkspaceError,\n isStorageWorkspaceError,\n} from './storage-workspace.error.js';\nexport { StorageFileWorkflow } from './storage-file-workflow.js';\nexport { DEFAULT_STORAGE_FILE_WORKFLOW_LIMITS } from './storage-file-workflow.types.js';\nexport type * from './storage-file-workflow.types.js';\nexport type * from './storage-file-catalog.types.js';\nexport {\n protectStorageFileWorkflowWorkspace,\n protectStorageFileWorkflowOperation,\n getStorageFileWorkflow,\n getStorageFileCatalog,\n type StorageFileWorkflowProtection,\n type StorageFileWorkflowWorkspace,\n type ProtectStorageFileWorkflowWorkspaceOptions,\n} from './storage-file-workflow.protection.js';\nexport {\n Aes256GcmStorageWorkspaceCursorCodec,\n STORAGE_WORKSPACE_CURSOR_VERSION,\n STORAGE_WORKSPACE_MAX_CURSOR_BYTES,\n type Aes256GcmStorageWorkspaceCursorCodecOptions,\n type StorageWorkspaceCursorCodec,\n type StorageWorkspaceCursorConfiguration,\n type StorageWorkspaceCursorEncodeOptions,\n} from './storage-workspace.cursor.js';\nexport {\n createStorageWorkspace,\n mountStorageWorkspace,\n} from './storage-workspace.js';\nexport {\n DEFAULT_STORAGE_WORKSPACE_LIMITS,\n STORAGE_WORKSPACE_PERMISSIONS,\n type MountStorageWorkspaceOptions,\n type StorageWorkspaceBody,\n type StorageWorkspaceByteFile,\n type StorageWorkspaceCopyOptions,\n type StorageWorkspaceDeleteOptions,\n type StorageWorkspace,\n type StorageWorkspaceDirectory,\n type StorageWorkspaceEntry,\n type StorageWorkspaceFile,\n type StorageWorkspaceLimits,\n type StorageWorkspaceListOptions,\n type StorageWorkspaceMountOptions,\n type StorageWorkspaceMutationOptions,\n type StorageWorkspaceOverwriteOptions,\n type StorageWorkspacePage,\n type StorageWorkspacePermission,\n type StorageWorkspaceReadOptions,\n type StorageWorkspaceSearchMatch,\n type StorageWorkspaceSearchOptions,\n type StorageWorkspaceTextFile,\n type StorageWorkspaceUnconditionalDeleteOptions,\n type StorageWorkspaceWriteOptions,\n} from './storage-workspace.types.js';\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { StorageTextEdit, StorageTextSearchResult } from '../core/storage-text.js';
|
|
2
|
+
import type { StorageTextWindow } from '../core/storage-streams.js';
|
|
3
|
+
import type { StorageFileWorkflowOperation, StorageFileWorkflowPage } from './storage-file-workflow.types.js';
|
|
4
|
+
export interface StorageCatalogFile {
|
|
5
|
+
readonly path: string;
|
|
6
|
+
readonly fileId: string;
|
|
7
|
+
readonly etag: string;
|
|
8
|
+
readonly size: number;
|
|
9
|
+
readonly contentType: string;
|
|
10
|
+
}
|
|
11
|
+
export interface StorageFileCatalogLimits {
|
|
12
|
+
readonly maxReadBytes: number;
|
|
13
|
+
readonly maxWriteBytes: number;
|
|
14
|
+
readonly maxPageSize: number;
|
|
15
|
+
readonly maxSearchScanBytes: number;
|
|
16
|
+
readonly maxSearchMatches: number;
|
|
17
|
+
readonly maxPathBytes: number;
|
|
18
|
+
}
|
|
19
|
+
export interface StorageCatalogPath extends StorageFileWorkflowOperation {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly expectedEtag?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface StorageCatalogPage extends StorageFileWorkflowOperation {
|
|
24
|
+
readonly offset?: number | undefined;
|
|
25
|
+
}
|
|
26
|
+
export interface StorageCatalogCommand extends StorageCatalogPath {
|
|
27
|
+
/** Opaque host-scoped command identity, stable across response-loss retries. */
|
|
28
|
+
readonly commandId: string;
|
|
29
|
+
}
|
|
30
|
+
/** Host catalog port. Implementations own persistence, conditional heads and replay. */
|
|
31
|
+
export interface StorageFileCatalogCapability<Receipt = unknown> {
|
|
32
|
+
readonly kind: 'storage-file-catalog';
|
|
33
|
+
readonly version: 1;
|
|
34
|
+
readonly limits: StorageFileCatalogLimits;
|
|
35
|
+
allows(permission: 'read' | 'write'): boolean;
|
|
36
|
+
list(input: StorageCatalogPage & {
|
|
37
|
+
readonly directory?: string | undefined;
|
|
38
|
+
}): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;
|
|
39
|
+
stat(input: StorageCatalogPath): Promise<StorageCatalogFile>;
|
|
40
|
+
search(input: StorageCatalogPage & {
|
|
41
|
+
readonly query: string;
|
|
42
|
+
}): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;
|
|
43
|
+
readWindow(input: StorageCatalogPath & StorageCatalogPage): Promise<StorageTextWindow & {
|
|
44
|
+
readonly path: string;
|
|
45
|
+
readonly fileId: string;
|
|
46
|
+
readonly etag: string;
|
|
47
|
+
readonly size: number;
|
|
48
|
+
readonly totalBytes: number;
|
|
49
|
+
}>;
|
|
50
|
+
searchContent(input: StorageCatalogPath & StorageCatalogPage & {
|
|
51
|
+
readonly expectedEtag: string;
|
|
52
|
+
readonly query: string;
|
|
53
|
+
}): Promise<StorageTextSearchResult & {
|
|
54
|
+
readonly path: string;
|
|
55
|
+
readonly etag: string;
|
|
56
|
+
}>;
|
|
57
|
+
write(input: StorageCatalogCommand & {
|
|
58
|
+
readonly content: string;
|
|
59
|
+
}): Promise<Receipt>;
|
|
60
|
+
edit(input: StorageCatalogCommand & {
|
|
61
|
+
readonly expectedEtag: string;
|
|
62
|
+
readonly change: StorageTextEdit;
|
|
63
|
+
}): Promise<Receipt>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=storage-file-catalog.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-file-catalog.types.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-file-catalog.types.js","sourceRoot":"","sources":["../../src/workspace/storage-file-catalog.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n StorageTextEdit,\n StorageTextSearchResult,\n} from '../core/storage-text.js';\nimport type { StorageTextWindow } from '../core/storage-streams.js';\nimport type {\n StorageFileWorkflowOperation,\n StorageFileWorkflowPage,\n} from './storage-file-workflow.types.js';\n\nexport interface StorageCatalogFile {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly contentType: string;\n}\nexport interface StorageFileCatalogLimits {\n readonly maxReadBytes: number;\n readonly maxWriteBytes: number;\n readonly maxPageSize: number;\n readonly maxSearchScanBytes: number;\n readonly maxSearchMatches: number;\n readonly maxPathBytes: number;\n}\nexport interface StorageCatalogPath extends StorageFileWorkflowOperation {\n readonly path: string;\n readonly expectedEtag?: string | undefined;\n}\nexport interface StorageCatalogPage extends StorageFileWorkflowOperation {\n readonly offset?: number | undefined;\n}\nexport interface StorageCatalogCommand extends StorageCatalogPath {\n /** Opaque host-scoped command identity, stable across response-loss retries. */\n readonly commandId: string;\n}\n/** Host catalog port. Implementations own persistence, conditional heads and replay. */\nexport interface StorageFileCatalogCapability<Receipt = unknown> {\n readonly kind: 'storage-file-catalog';\n readonly version: 1;\n readonly limits: StorageFileCatalogLimits;\n allows(permission: 'read' | 'write'): boolean;\n list(\n input: StorageCatalogPage & { readonly directory?: string | undefined },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n stat(input: StorageCatalogPath): Promise<StorageCatalogFile>;\n search(\n input: StorageCatalogPage & { readonly query: string },\n ): Promise<StorageFileWorkflowPage<StorageCatalogFile>>;\n readWindow(input: StorageCatalogPath & StorageCatalogPage): Promise<\n StorageTextWindow & {\n readonly path: string;\n readonly fileId: string;\n readonly etag: string;\n readonly size: number;\n readonly totalBytes: number;\n }\n >;\n searchContent(\n input: StorageCatalogPath &\n StorageCatalogPage & {\n readonly expectedEtag: string;\n readonly query: string;\n },\n ): Promise<\n StorageTextSearchResult & { readonly path: string; readonly etag: string }\n >;\n write(\n input: StorageCatalogCommand & { readonly content: string },\n ): Promise<Receipt>;\n edit(\n input: StorageCatalogCommand & {\n readonly expectedEtag: string;\n readonly change: StorageTextEdit;\n },\n ): Promise<Receipt>;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type MountStorageFileWorkflowOptions, type StorageFileWorkflowCapability, type StorageFileWorkflowOptions } from './storage-file-workflow.types.js';
|
|
2
|
+
export declare class StorageFileWorkflow<Scope, Receipt> {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(options: StorageFileWorkflowOptions<Scope, Receipt>);
|
|
5
|
+
mount(scope: Scope, options?: MountStorageFileWorkflowOptions): StorageFileWorkflowCapability<Receipt>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=storage-file-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-file-workflow.d.ts","sourceRoot":"","sources":["../../src/workspace/storage-file-workflow.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,+BAA+B,EAGpC,KAAK,6BAA6B,EAGlC,KAAK,0BAA0B,EAIhC,MAAM,kCAAkC,CAAC;AAE1C,qBAAa,mBAAmB,CAAC,KAAK,EAAE,OAAO;;IAE7C,YAAY,OAAO,EAAE,0BAA0B,CAAC,KAAK,EAAE,OAAO,CAAC,EAE9D;IAED,KAAK,CACH,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,+BAAoC,GAC5C,6BAA6B,CAAC,OAAO,CAAC,CAgYxC;CA6FF"}
|