@nestm/storage 0.1.0-alpha.0 → 0.1.0-alpha.10
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 +264 -0
- package/README.md +724 -25
- package/SECURITY.md +101 -0
- package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts +91 -0
- package/dist/ai-sdk/ai-sdk-workspace-tools.d.ts.map +1 -0
- package/dist/ai-sdk/ai-sdk-workspace-tools.js +491 -0
- package/dist/ai-sdk/ai-sdk-workspace-tools.js.map +1 -0
- package/dist/ai-sdk/index.d.ts +2 -0
- package/dist/ai-sdk/index.d.ts.map +1 -0
- package/dist/ai-sdk/index.js +2 -0
- package/dist/ai-sdk/index.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/files-sdk/files-sdk.driver.d.ts +85 -3
- package/dist/files-sdk/files-sdk.driver.d.ts.map +1 -1
- package/dist/files-sdk/files-sdk.driver.js +1437 -37
- package/dist/files-sdk/files-sdk.driver.js.map +1 -1
- package/dist/files-sdk/fs/index.d.ts +42 -0
- package/dist/files-sdk/fs/index.d.ts.map +1 -0
- package/dist/files-sdk/fs/index.js +1117 -0
- package/dist/files-sdk/fs/index.js.map +1 -0
- package/dist/files-sdk/index.d.ts +1 -1
- package/dist/files-sdk/index.d.ts.map +1 -1
- package/dist/files-sdk/index.js.map +1 -1
- package/dist/files-sdk/provider/index.d.ts +58 -0
- package/dist/files-sdk/provider/index.d.ts.map +1 -0
- package/dist/files-sdk/provider/index.js +147 -0
- package/dist/files-sdk/provider/index.js.map +1 -0
- package/dist/files-sdk/s3/construction-metadata.d.ts +9 -0
- package/dist/files-sdk/s3/construction-metadata.d.ts.map +1 -0
- package/dist/files-sdk/s3/construction-metadata.js +24 -0
- package/dist/files-sdk/s3/construction-metadata.js.map +1 -0
- package/dist/files-sdk/s3/index.d.ts +54 -0
- package/dist/files-sdk/s3/index.d.ts.map +1 -0
- package/dist/files-sdk/s3/index.js +1505 -0
- package/dist/files-sdk/s3/index.js.map +1 -0
- package/dist/gateway/index.d.ts +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/storage-gateway-fastify-parser.d.ts.map +1 -1
- package/dist/gateway/storage-gateway-fastify-parser.js.map +1 -1
- package/dist/gateway/storage-gateway.controller.d.ts +12 -11
- package/dist/gateway/storage-gateway.controller.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.controller.js +240 -70
- package/dist/gateway/storage-gateway.controller.js.map +1 -1
- package/dist/gateway/storage-gateway.guard.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.guard.js.map +1 -1
- package/dist/gateway/storage-gateway.module.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.module.js +60 -1
- package/dist/gateway/storage-gateway.module.js.map +1 -1
- package/dist/gateway/storage-gateway.tokens.d.ts +1 -0
- package/dist/gateway/storage-gateway.tokens.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.tokens.js +1 -0
- package/dist/gateway/storage-gateway.tokens.js.map +1 -1
- package/dist/gateway/storage-gateway.types.d.ts +53 -10
- package/dist/gateway/storage-gateway.types.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.types.js.map +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/inject-storage.decorator.js.map +1 -1
- package/dist/storage-etag.d.ts +13 -0
- package/dist/storage-etag.d.ts.map +1 -0
- package/dist/storage-etag.js +31 -0
- package/dist/storage-etag.js.map +1 -0
- package/dist/storage-upload-control.d.ts.map +1 -1
- package/dist/storage.client.d.ts +15 -3
- package/dist/storage.client.d.ts.map +1 -1
- package/dist/storage.client.js +204 -2
- package/dist/storage.client.js.map +1 -1
- package/dist/storage.driver.d.ts +28 -1
- package/dist/storage.driver.d.ts.map +1 -1
- package/dist/storage.driver.js.map +1 -1
- package/dist/storage.error.d.ts +17 -10
- package/dist/storage.error.d.ts.map +1 -1
- package/dist/storage.error.js +47 -1
- package/dist/storage.error.js.map +1 -1
- package/dist/storage.module.d.ts.map +1 -1
- package/dist/storage.module.js.map +1 -1
- package/dist/storage.service.d.ts.map +1 -1
- package/dist/storage.service.js +28 -3
- package/dist/storage.service.js.map +1 -1
- package/dist/storage.tokens.js.map +1 -1
- package/dist/storage.types.d.ts +150 -1
- package/dist/storage.types.d.ts.map +1 -1
- package/dist/storage.types.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/provider-conformance.d.ts +65 -0
- package/dist/testing/provider-conformance.d.ts.map +1 -0
- package/dist/testing/provider-conformance.js +869 -0
- package/dist/testing/provider-conformance.js.map +1 -0
- package/dist/workspace/index.d.ts +5 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +5 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/storage-workspace.cursor.d.ts +71 -0
- package/dist/workspace/storage-workspace.cursor.d.ts.map +1 -0
- package/dist/workspace/storage-workspace.cursor.js +408 -0
- package/dist/workspace/storage-workspace.cursor.js.map +1 -0
- package/dist/workspace/storage-workspace.d.ts +6 -0
- package/dist/workspace/storage-workspace.d.ts.map +1 -0
- package/dist/workspace/storage-workspace.error.d.ts +32 -0
- package/dist/workspace/storage-workspace.error.d.ts.map +1 -0
- package/dist/workspace/storage-workspace.error.js +75 -0
- package/dist/workspace/storage-workspace.error.js.map +1 -0
- package/dist/workspace/storage-workspace.js +849 -0
- package/dist/workspace/storage-workspace.js.map +1 -0
- package/dist/workspace/storage-workspace.path.d.ts +9 -0
- package/dist/workspace/storage-workspace.path.d.ts.map +1 -0
- package/dist/workspace/storage-workspace.path.js +68 -0
- package/dist/workspace/storage-workspace.path.js.map +1 -0
- package/dist/workspace/storage-workspace.types.d.ts +123 -0
- package/dist/workspace/storage-workspace.types.d.ts.map +1 -0
- package/dist/workspace/storage-workspace.types.js +22 -0
- package/dist/workspace/storage-workspace.types.js.map +1 -0
- package/package.json +103 -35
package/SECURITY.md
CHANGED
|
@@ -23,3 +23,104 @@ cross-store pruning, or dependency compromise are especially useful.
|
|
|
23
23
|
For a vulnerability originating in NestJS, `files-sdk`, or a provider SDK,
|
|
24
24
|
follow that project's security policy as well. You may still report it here
|
|
25
25
|
privately when this integration needs a mitigation.
|
|
26
|
+
|
|
27
|
+
## Gateway security boundary
|
|
28
|
+
|
|
29
|
+
Mounting the optional HTTP gateway requires both authentication guards and a
|
|
30
|
+
`StorageGatewayKeyPolicy`. The policy receives parsed paths and must derive the
|
|
31
|
+
provider key space from trusted request context. Do not treat a client prefix
|
|
32
|
+
or object key as a tenant identifier. `unsafeAllowUnscopedKeys` exists only to
|
|
33
|
+
migrate trusted single-tenant deployments and is unsafe on an exposed gateway.
|
|
34
|
+
|
|
35
|
+
Signed URL expiry, signed-upload byte size, and signed-upload MIME are bounded
|
|
36
|
+
by module configuration and cannot be increased by a request. Only `inline`
|
|
37
|
+
and `attachment` content dispositions are accepted. File type still must be
|
|
38
|
+
verified from magic bytes after upload; a signed MIME condition proves only
|
|
39
|
+
what header the uploader supplied. The gateway rejects signed-upload drivers
|
|
40
|
+
that do not advertise provider-enforced content-type and size-range policies.
|
|
41
|
+
It also rejects download adapters that cannot guarantee the requested expiry;
|
|
42
|
+
in particular, the S3 bridge does not treat `publicBaseUrl` links as expiring.
|
|
43
|
+
|
|
44
|
+
For staged uploads on S3, use `promote`/`promoteTo` with the ETag returned by
|
|
45
|
+
the validated `head` or with an immutable provider version. Ordinary `copy`
|
|
46
|
+
does not protect against a staging-key replay between validation and copy.
|
|
47
|
+
Conditional promotion keeps the staging source; delete it only after the
|
|
48
|
+
application's metadata transaction commits.
|
|
49
|
+
|
|
50
|
+
## Workspace security boundary
|
|
51
|
+
|
|
52
|
+
`StorageWorkspace` is a narrowing capability for storage operations. Construct
|
|
53
|
+
it from trusted application context, keep the underlying `StorageClient` and
|
|
54
|
+
mount prefix private, and pass only the workspace or its AI tool set to
|
|
55
|
+
untrusted agent code. A tenant id, run id, prefix, provider cursor, snapshot id,
|
|
56
|
+
or fork id supplied by a model is not a safe mount coordinate.
|
|
57
|
+
|
|
58
|
+
The workspace accepts only canonical mount-relative POSIX paths and rechecks
|
|
59
|
+
every key returned by a driver before unscoping it. Pagination cursors are bound
|
|
60
|
+
to the store, normalized physical prefix, stable mount identity, trusted
|
|
61
|
+
tenant/workspace scope, operation, complete effective limits, normalized query,
|
|
62
|
+
and expiry. Provider continuations and prefixes stay inside the encrypted or
|
|
63
|
+
server-side payload. Both layers are non-consuming: a durable opaque token
|
|
64
|
+
store must read rather than consume a record, and an embedded provider cursor
|
|
65
|
+
must remain replayable through a fresh compatible driver against the same
|
|
66
|
+
backend namespace while that provider cursor remains valid and available.
|
|
67
|
+
Provider cursors cannot depend on process-local state; an adapter for a
|
|
68
|
+
consuming or instance-bound backend token must materialize a stable continuation
|
|
69
|
+
before exposing paginated `StorageDriver.list` results.
|
|
70
|
+
|
|
71
|
+
Under unchanged provider-visible state, cursors are reusable while their
|
|
72
|
+
provider continuation remains valid and available. The authenticated expiry is
|
|
73
|
+
an authorization ceiling, not a guarantee of provider-token lifetime, snapshot
|
|
74
|
+
isolation, provider/network availability, or valid credentials. Provider
|
|
75
|
+
invalidation remains an operational failure, and concurrent mutations remain
|
|
76
|
+
subject to provider ordering, duplicate, and omission semantics.
|
|
77
|
+
|
|
78
|
+
Production pagination must configure either the built-in AES-256-GCM codec with
|
|
79
|
+
a dedicated shared 32-byte key ring or an authenticated shared durable token
|
|
80
|
+
store. Do not reuse an authentication, session, storage-provider, or encryption
|
|
81
|
+
key from another purpose. All replicas must use the same stable identities and
|
|
82
|
+
key ring, compatible driver configuration, and logical backend namespace. New
|
|
83
|
+
cursors use the active key id; retain prior keys for at least the maximum cursor
|
|
84
|
+
TTL during rotation. Dropping a key, changing a binding field, or restarting
|
|
85
|
+
with a different ephemeral key intentionally invalidates outstanding cursors.
|
|
86
|
+
Tokens and decoded payloads are bounded, and malformed, altered, expired,
|
|
87
|
+
cross-query, cross-operation, cross-workspace, and cross-store cursors fail
|
|
88
|
+
closed.
|
|
89
|
+
|
|
90
|
+
Permissions, byte limits, result limits, and conditional mutation preconditions
|
|
91
|
+
are enforced inside the capability; tool omission and user approval are
|
|
92
|
+
additional workflow controls, not the authorization boundary.
|
|
93
|
+
|
|
94
|
+
Conditional mutations can still have an ambiguous outcome when a remote
|
|
95
|
+
provider commits and then loses or violates its response, or when a configured
|
|
96
|
+
post-operation plugin fails after the driver has committed. Known post-commit
|
|
97
|
+
failures report `StorageError.applied === true`; a conditional upload also
|
|
98
|
+
carries `appliedEtag` when its committed generation is known. This is positive
|
|
99
|
+
evidence, not a complete remote-commit oracle: a timeout, connection loss, or
|
|
100
|
+
exhausted retry can lose a provider success response and still leave
|
|
101
|
+
`applied === false`. Do not reissue an ambiguous predicate blindly. Reconcile
|
|
102
|
+
the logical destination first, using an exact ETag read when `appliedEtag` is
|
|
103
|
+
available and inspecting the relevant source/destination state for copy or
|
|
104
|
+
delete. Create-only and ETag preconditions prevent a blind retry from silently
|
|
105
|
+
overwriting a different object, but they cannot make a multi-object move
|
|
106
|
+
transactionally atomic.
|
|
107
|
+
|
|
108
|
+
This guarantee covers calls made through `StorageWorkspace`. It does not
|
|
109
|
+
confine arbitrary `node:fs`, shell, subprocess, or native-code access in the
|
|
110
|
+
same process. A coding harness with built-in shell or filesystem tools must run
|
|
111
|
+
inside an OS sandbox (container, VM, or equivalent) that exposes only a
|
|
112
|
+
materialized workspace. Setting `cwd` to a workspace directory is not
|
|
113
|
+
isolation.
|
|
114
|
+
|
|
115
|
+
For local filesystem storage, use a dedicated service-owned root and route all
|
|
116
|
+
in-process mutations through the package-decorated adapter; its ordinary and
|
|
117
|
+
conditional mutation paths share one lock domain. A separate process,
|
|
118
|
+
unwrapped adapter, or direct filesystem writer can bypass that coordination and
|
|
119
|
+
must not mutate the tree concurrently. High-level Node filesystem checks reject
|
|
120
|
+
symlinks and hard-linked object files in existing workspace read and mutation
|
|
121
|
+
paths, including metadata sidecars, but cannot provide a race-proof boundary
|
|
122
|
+
against an actor that can replace path components between validation and use.
|
|
123
|
+
For that threat model, mount only the workspace into a separate
|
|
124
|
+
UID/container/VM and synchronize approved results back through storage. The
|
|
125
|
+
local adapter also commits the body and metadata sidecar as two files; a process
|
|
126
|
+
crash between their atomic renames can require reconciliation.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type JSONValue, type ToolSet } from 'ai';
|
|
2
|
+
import { type StorageWorkspace } from '../workspace/index.js';
|
|
3
|
+
import { type StorageErrorCode as StorageErrorCodeValue } from '../storage.error.js';
|
|
4
|
+
export declare const AI_SDK_WORKSPACE_TOOL_NAMES: readonly ['workspace_list', 'workspace_stat', 'workspace_read_file', 'workspace_search', 'workspace_write_file', 'workspace_copy_file', 'workspace_move_file', 'workspace_delete_file'];
|
|
5
|
+
export type AiSdkWorkspaceToolName = (typeof AI_SDK_WORKSPACE_TOOL_NAMES)[number];
|
|
6
|
+
export type AiSdkWorkspaceMutationToolName = Extract<AiSdkWorkspaceToolName, 'workspace_write_file' | 'workspace_copy_file' | 'workspace_move_file' | 'workspace_delete_file'>;
|
|
7
|
+
/**
|
|
8
|
+
* Approval policy for mutation tools. An omitted entry defaults to requiring
|
|
9
|
+
* approval, matching an omitted policy.
|
|
10
|
+
*/
|
|
11
|
+
export type AiSdkWorkspaceApprovalConfig = boolean | Partial<Record<AiSdkWorkspaceMutationToolName, boolean>>;
|
|
12
|
+
export type AiSdkWorkspaceMutationMode = 'conditional' | 'last-write-wins';
|
|
13
|
+
export interface AiSdkWorkspaceCreateConflict {
|
|
14
|
+
/** The logical destination inside the mounted workspace. */
|
|
15
|
+
readonly path: string;
|
|
16
|
+
}
|
|
17
|
+
export type AiSdkWorkspaceCreateConflictMapper<Result extends JSONValue> = (conflict: AiSdkWorkspaceCreateConflict) => PromiseLike<Result> | Result;
|
|
18
|
+
export interface CreateAiSdkWorkspaceToolsOptions<CreateConflictResult extends JSONValue = never> {
|
|
19
|
+
/** The already-mounted, policy-enforcing workspace exposed to the tools. */
|
|
20
|
+
workspace: StorageWorkspace;
|
|
21
|
+
/**
|
|
22
|
+
* Optional tighter read ceiling. Values above the workspace ceiling are
|
|
23
|
+
* clamped; the model cannot choose or raise this value.
|
|
24
|
+
*/
|
|
25
|
+
maxReadBytes?: number;
|
|
26
|
+
/** Mutation tools require approval by default. */
|
|
27
|
+
requireApproval?: AiSdkWorkspaceApprovalConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Selects the mutation contract exposed to the model. Conditional mode is
|
|
30
|
+
* the default; last-write-wins uses the workspace's ordinary Files path.
|
|
31
|
+
*/
|
|
32
|
+
mutationMode?: AiSdkWorkspaceMutationMode;
|
|
33
|
+
/**
|
|
34
|
+
* Maps an atomic create collision to an application result. When omitted,
|
|
35
|
+
* the collision remains an AiSdkWorkspaceToolError like every other storage
|
|
36
|
+
* failure. Replace conflicts are never mapped by this hook. This option is
|
|
37
|
+
* valid only when mutationMode is conditional.
|
|
38
|
+
*/
|
|
39
|
+
mapCreateConflict?: AiSdkWorkspaceCreateConflictMapper<CreateConflictResult>;
|
|
40
|
+
}
|
|
41
|
+
export type AiSdkWorkspaceToolErrorCode = StorageErrorCodeValue;
|
|
42
|
+
export interface AiSdkWorkspaceToolErrorOptions {
|
|
43
|
+
/** True when the failed operation may already have committed. */
|
|
44
|
+
readonly applied?: boolean;
|
|
45
|
+
/** Canonical ETag of the committed object, when the provider returned one. */
|
|
46
|
+
readonly appliedEtag?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Safe error exposed at the AI tool boundary. It deliberately carries no
|
|
50
|
+
* provider error, storage key, mount prefix, store name, or cause. Applied
|
|
51
|
+
* reconciliation metadata is retained so callers do not blindly retry a
|
|
52
|
+
* mutation that may already have committed.
|
|
53
|
+
*/
|
|
54
|
+
export declare class AiSdkWorkspaceToolError extends Error {
|
|
55
|
+
readonly code: AiSdkWorkspaceToolErrorCode;
|
|
56
|
+
readonly applied?: true;
|
|
57
|
+
readonly appliedEtag?: string;
|
|
58
|
+
constructor(code: AiSdkWorkspaceToolErrorCode, options?: AiSdkWorkspaceToolErrorOptions);
|
|
59
|
+
}
|
|
60
|
+
export interface AiSdkWorkspaceFileResult {
|
|
61
|
+
kind: 'file';
|
|
62
|
+
path: string;
|
|
63
|
+
name: string;
|
|
64
|
+
size: number;
|
|
65
|
+
contentType: string;
|
|
66
|
+
etag?: string;
|
|
67
|
+
lastModified?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface AiSdkWorkspaceDirectoryResult {
|
|
70
|
+
kind: 'directory';
|
|
71
|
+
path: string;
|
|
72
|
+
name: string;
|
|
73
|
+
}
|
|
74
|
+
export type AiSdkWorkspaceEntryResult = AiSdkWorkspaceFileResult | AiSdkWorkspaceDirectoryResult;
|
|
75
|
+
export interface AiSdkWorkspaceTextFileResult extends AiSdkWorkspaceFileResult {
|
|
76
|
+
text: string;
|
|
77
|
+
}
|
|
78
|
+
export interface AiSdkWorkspacePageResult {
|
|
79
|
+
entries: AiSdkWorkspaceEntryResult[];
|
|
80
|
+
cursor?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates Vercel AI SDK tools backed only by a mounted StorageWorkspace.
|
|
84
|
+
*
|
|
85
|
+
* A tool is omitted unless the workspace grants its required permission.
|
|
86
|
+
* The workspace remains the enforcing boundary if a retained tool reference
|
|
87
|
+
* is invoked after further narrowing.
|
|
88
|
+
*/
|
|
89
|
+
export declare function createAiSdkWorkspaceTools<CreateConflictResult extends JSONValue = never>({ workspace, maxReadBytes: requestedMaxReadBytes, mutationMode, requireApproval, mapCreateConflict, }: CreateAiSdkWorkspaceToolsOptions<CreateConflictResult>): ToolSet;
|
|
90
|
+
export declare function isAiSdkWorkspaceMutationToolName(value: string): value is AiSdkWorkspaceMutationToolName;
|
|
91
|
+
//# sourceMappingURL=ai-sdk-workspace-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-workspace-tools.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/ai-sdk-workspace-tools.ts"],"names":[],"mappings":"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"}
|