@w3kits/sdk 0.1.0

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 (42) hide show
  1. package/README.md +29 -0
  2. package/dist/app-file.d.ts +39 -0
  3. package/dist/app-file.d.ts.map +1 -0
  4. package/dist/app-file.js +81 -0
  5. package/dist/app-file.js.map +1 -0
  6. package/dist/browser.d.ts +12 -0
  7. package/dist/browser.d.ts.map +1 -0
  8. package/dist/browser.js +12 -0
  9. package/dist/browser.js.map +1 -0
  10. package/dist/container.d.ts +36 -0
  11. package/dist/container.d.ts.map +1 -0
  12. package/dist/container.js +125 -0
  13. package/dist/container.js.map +1 -0
  14. package/dist/index.d.ts +12 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +12 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/local-cache.d.ts +207 -0
  19. package/dist/local-cache.d.ts.map +1 -0
  20. package/dist/local-cache.js +187 -0
  21. package/dist/local-cache.js.map +1 -0
  22. package/dist/path-mapping.d.ts +79 -0
  23. package/dist/path-mapping.d.ts.map +1 -0
  24. package/dist/path-mapping.js +156 -0
  25. package/dist/path-mapping.js.map +1 -0
  26. package/dist/plugin.d.ts +34 -0
  27. package/dist/plugin.d.ts.map +1 -0
  28. package/dist/plugin.js +124 -0
  29. package/dist/plugin.js.map +1 -0
  30. package/dist/profile-app-file.d.ts +202 -0
  31. package/dist/profile-app-file.d.ts.map +1 -0
  32. package/dist/profile-app-file.js +352 -0
  33. package/dist/profile-app-file.js.map +1 -0
  34. package/dist/r2-client.d.ts +76 -0
  35. package/dist/r2-client.d.ts.map +1 -0
  36. package/dist/r2-client.js +56 -0
  37. package/dist/r2-client.js.map +1 -0
  38. package/dist/storage/index.d.ts +67 -0
  39. package/dist/storage/index.d.ts.map +1 -0
  40. package/dist/storage/index.js +111 -0
  41. package/dist/storage/index.js.map +1 -0
  42. package/package.json +73 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Defines SDK-owned local-first cache model and operation log helpers.
3
+ * @owner w3kits-sdk
4
+ * @module sdk
5
+ * @boundary local-cache
6
+ */
7
+ export const DB_NAME = "w3kits-local-first-vfs";
8
+ export const DB_VERSION = 2;
9
+ export const OBJECT_STORE = "objects";
10
+ export const BODY_STORE = "bodies";
11
+ export const OPERATION_STORE = "operations";
12
+ export const GENERATION_STORE = "generations";
13
+ export const OPFS_ROOT = "w3kits-local-first-vfs-v1";
14
+ export const OPEN_DB_TIMEOUT_MS = 2500;
15
+ export const DEFAULT_INLINE_BODY_BYTES = 256 * 1024;
16
+ export const DEFAULT_RETRY_BASE_DELAY_MS = 1000;
17
+ export const DEFAULT_MAX_RETRY_DELAY_MS = 30_000;
18
+ /**
19
+ * Converts local-first body input to a standalone ArrayBuffer.
20
+ */
21
+ export function toArrayBuffer(body) {
22
+ if (typeof body === "string")
23
+ return new TextEncoder().encode(body).buffer;
24
+ if (body instanceof Uint8Array)
25
+ return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);
26
+ return body;
27
+ }
28
+ /**
29
+ * Normalizes an object key and rejects path escapes/control characters.
30
+ */
31
+ export function normalizeKey(input, options = {}) {
32
+ const raw = input.trim().replace(/^\/+/, "").replace(/\/+$/, "");
33
+ if (!raw) {
34
+ if (options.allowRoot)
35
+ return "";
36
+ throw new Error("invalid_object_key");
37
+ }
38
+ const segments = [];
39
+ for (const segment of raw.split("/")) {
40
+ if (!segment || segment === ".")
41
+ continue;
42
+ if (segment === "..")
43
+ throw new Error("path_escape");
44
+ if (/[\u0000-\u001f\u007f\\]/u.test(segment))
45
+ throw new Error("invalid_object_key");
46
+ segments.push(segment);
47
+ }
48
+ if (segments.length === 0) {
49
+ if (options.allowRoot)
50
+ return "";
51
+ throw new Error("invalid_object_key");
52
+ }
53
+ return segments.join("/");
54
+ }
55
+ /**
56
+ * Builds the local-first cache scope id.
57
+ */
58
+ export function scopeIdFor(userId, cacheGeneration) {
59
+ return userId + ":" + cacheGeneration;
60
+ }
61
+ /**
62
+ * Builds the stable local-first object row id.
63
+ */
64
+ export function objectId(scopeId, bucket, key) {
65
+ return scopeId + ":" + bucket + ":" + normalizeKey(key, { allowRoot: true });
66
+ }
67
+ /**
68
+ * Creates a local operation id.
69
+ */
70
+ export function createOperationId() {
71
+ return typeof crypto !== "undefined" && "randomUUID" in crypto
72
+ ? crypto.randomUUID()
73
+ : "op-" + Date.now() + "-" + Math.random().toString(36).slice(2);
74
+ }
75
+ /**
76
+ * Returns the current ISO timestamp for local-first records.
77
+ */
78
+ export function nowIso() {
79
+ return new Date().toISOString();
80
+ }
81
+ /**
82
+ * Computes bounded exponential retry delay for failed local-first operations.
83
+ */
84
+ export function retryDelayMs(options, attempts) {
85
+ const base = options.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS;
86
+ const max = options.maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS;
87
+ return Math.min(max, base * 2 ** Math.max(0, attempts - 1));
88
+ }
89
+ /**
90
+ * Computes the next retry timestamp for a failed local-first operation.
91
+ */
92
+ export function nextAttemptIso(options, attempts) {
93
+ return new Date(Date.now() + retryDelayMs(options, attempts)).toISOString();
94
+ }
95
+ /**
96
+ * Encodes an OPFS-safe path segment.
97
+ */
98
+ export function safeOpfsSegment(value) {
99
+ return encodeURIComponent(value).replace(/[!'()*]/g, (char) => "%" + char.charCodeAt(0).toString(16).toUpperCase());
100
+ }
101
+ /**
102
+ * Decides whether a body should try OPFS storage before IndexedDB storage.
103
+ */
104
+ export function shouldTryOpfs(options, bodySize) {
105
+ if (options.bodyStore === "indexeddb")
106
+ return false;
107
+ if (options.bodyStore === "opfs")
108
+ return true;
109
+ return bodySize > (options.inlineBodyBytes ?? DEFAULT_INLINE_BODY_BYTES);
110
+ }
111
+ /**
112
+ * Filters local-first objects by scope, bucket, and prefix.
113
+ */
114
+ export function filterLocalFirstListRows(rows, scopeId, bucket, prefix) {
115
+ return rows
116
+ .filter((row) => row.scopeId === scopeId && row.bucket === bucket)
117
+ .filter((row) => !prefix ||
118
+ row.key === prefix ||
119
+ row.key.startsWith(prefix.endsWith("/") ? prefix : prefix + "/"));
120
+ }
121
+ /**
122
+ * Creates an operation log row with normalized fields.
123
+ */
124
+ export function createQueuedOperation(input) {
125
+ const now = input.createdAt ?? nowIso();
126
+ return {
127
+ ...input,
128
+ key: normalizeKey(input.key, { allowRoot: input.type === "mkdir" }),
129
+ sourceKey: input.sourceKey
130
+ ? normalizeKey(input.sourceKey, { allowRoot: false })
131
+ : undefined,
132
+ operationId: input.operationId ?? createOperationId(),
133
+ status: input.status ?? "queued",
134
+ attempts: input.attempts ?? 0,
135
+ createdAt: now,
136
+ updatedAt: input.updatedAt ?? now,
137
+ };
138
+ }
139
+ /**
140
+ * Marks a queued operation as failed because auth/capability refresh is required.
141
+ */
142
+ export function markQueuedAuthFailure(operation, options) {
143
+ const attempts = operation.attempts + 1;
144
+ const updatedAt = nowIso();
145
+ return {
146
+ ...operation,
147
+ status: "failed",
148
+ attempts,
149
+ lastError: "storage_auth_failed",
150
+ nextAttemptAt: nextAttemptIso(options, attempts),
151
+ updatedAt,
152
+ };
153
+ }
154
+ /**
155
+ * In-memory operation log used by browser tests and non-persistent SDK adapters.
156
+ */
157
+ export class InMemoryOperationLog {
158
+ operations = new Map();
159
+ /**
160
+ * Enqueues an operation and returns the stored row.
161
+ */
162
+ enqueue(input) {
163
+ const operation = createQueuedOperation(input);
164
+ this.operations.set(operation.operationId, operation);
165
+ return operation;
166
+ }
167
+ /**
168
+ * Lists operations that still need remote flush attempts.
169
+ */
170
+ pending() {
171
+ return [...this.operations.values()].filter((operation) => ["queued", "failed"].includes(operation.status));
172
+ }
173
+ /**
174
+ * Replaces one operation row.
175
+ */
176
+ update(operation) {
177
+ this.operations.set(operation.operationId, operation);
178
+ return operation;
179
+ }
180
+ /**
181
+ * Returns all operations in insertion order.
182
+ */
183
+ all() {
184
+ return [...this.operations.values()];
185
+ }
186
+ }
187
+ //# sourceMappingURL=local-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-cache.js","sourceRoot":"","sources":["../src/local-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Defines client-visible path mapping for W3Kits storage capabilities.
3
+ * @owner w3kits-sdk
4
+ * @module sdk
5
+ * @boundary path-mapping
6
+ * @business Keeps /home/agent file semantics client-owned while Core issues scoped R2 capabilities.
7
+ */
8
+ export declare const VISIBLE_HOME_ROOT = "/home/agent";
9
+ export declare const APPLICATIONS_ROOT = "/home/agent/Applications";
10
+ export declare const DEFAULT_PROFILE_ID = "default";
11
+ export type StorageScope = {
12
+ userId: string;
13
+ profileId?: string | null;
14
+ };
15
+ export type VisiblePathMapping = {
16
+ userId: string;
17
+ profileId: string;
18
+ visiblePath: string;
19
+ relativeHomePath: string;
20
+ r2Key: string;
21
+ };
22
+ /**
23
+ * Represents SDK path and capability validation failures.
24
+ */
25
+ export declare class W3KitsStorageError extends Error {
26
+ readonly code: "invalid_user_id" | "invalid_profile_id" | "invalid_plugin_slug" | "invalid_visible_path" | "path_escape" | "outside_visible_root";
27
+ /**
28
+ * Initializes a storage error with a stable code.
29
+ */
30
+ constructor(code: "invalid_user_id" | "invalid_profile_id" | "invalid_plugin_slug" | "invalid_visible_path" | "path_escape" | "outside_visible_root", message: string);
31
+ }
32
+ /**
33
+ * Normalizes a Core-authenticated user id for SDK key mapping.
34
+ */
35
+ export declare function normalizeUserId(userId: string): string;
36
+ /**
37
+ * Normalizes a selected W3Kits profile id.
38
+ */
39
+ export declare function normalizeProfileId(profileId?: string | null): string;
40
+ /**
41
+ * Normalizes plugin slugs used in .app and config roots.
42
+ */
43
+ export declare function normalizePluginSlug(pluginSlug: string): string;
44
+ /**
45
+ * Normalizes a root-relative path without allowing escape segments.
46
+ */
47
+ export declare function normalizeRelativePath(input: string): string;
48
+ /**
49
+ * Converts a visible /home/agent path to a normalized relative home path.
50
+ */
51
+ export declare function visiblePathToHomeRelative(visiblePath: string): string;
52
+ /**
53
+ * Converts a relative home path back to the visible path contract.
54
+ */
55
+ export declare function homeRelativeToVisiblePath(relativeHomePath: string): string;
56
+ /**
57
+ * Builds the R2 key for a visible /home/agent path.
58
+ */
59
+ export declare function visiblePathToR2Key(visiblePath: string, scope: StorageScope): string;
60
+ /**
61
+ * Returns all mapping components for a visible /home/agent path.
62
+ */
63
+ export declare function mapVisiblePathToR2(visiblePath: string, scope: StorageScope): VisiblePathMapping;
64
+ /**
65
+ * Builds a plugin config root under /home/agent.
66
+ */
67
+ export declare function pluginConfigRoot(pluginSlug: string): string;
68
+ /**
69
+ * Builds the target .app path for installed plugin launchers.
70
+ */
71
+ export declare function appFilePath(pluginSlug: string): string;
72
+ /**
73
+ * Creates a conflict-copy path under the same visible directory.
74
+ */
75
+ export declare function conflictCopyVisiblePath(visiblePath: string, input?: {
76
+ label?: string;
77
+ now?: Date;
78
+ }): string;
79
+ //# sourceMappingURL=path-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-mapping.d.ts","sourceRoot":"","sources":["../src/path-mapping.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,6BAAsC,CAAC;AACrE,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAI5C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAKzB,IAAI,EAChB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,sBAAsB,GACtB,aAAa,GACb,sBAAsB;IAV5B;;OAEG;gBAEe,IAAI,EAChB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,sBAAsB,GACtB,aAAa,GACb,sBAAsB,EAC1B,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAepE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAS9D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB3D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAiBrE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,GAClB,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,GAClB,kBAAkB,CAapB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GACzC,MAAM,CAcR"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Defines client-visible path mapping for W3Kits storage capabilities.
3
+ * @owner w3kits-sdk
4
+ * @module sdk
5
+ * @boundary path-mapping
6
+ * @business Keeps /home/agent file semantics client-owned while Core issues scoped R2 capabilities.
7
+ */
8
+ export const VISIBLE_HOME_ROOT = "/home/agent";
9
+ export const APPLICATIONS_ROOT = `${VISIBLE_HOME_ROOT}/Applications`;
10
+ export const DEFAULT_PROFILE_ID = "default";
11
+ const CONTROL_CHARS = /[\u0000-\u001f\u007f]/u;
12
+ /**
13
+ * Represents SDK path and capability validation failures.
14
+ */
15
+ export class W3KitsStorageError extends Error {
16
+ code;
17
+ /**
18
+ * Initializes a storage error with a stable code.
19
+ */
20
+ constructor(code, message) {
21
+ super(message);
22
+ this.code = code;
23
+ this.name = "W3KitsStorageError";
24
+ }
25
+ }
26
+ /**
27
+ * Normalizes a Core-authenticated user id for SDK key mapping.
28
+ */
29
+ export function normalizeUserId(userId) {
30
+ const normalized = userId.trim();
31
+ if (!/^[A-Za-z0-9._:@-]+$/u.test(normalized)) {
32
+ throw new W3KitsStorageError("invalid_user_id", "Invalid user id");
33
+ }
34
+ return normalized;
35
+ }
36
+ /**
37
+ * Normalizes a selected W3Kits profile id.
38
+ */
39
+ export function normalizeProfileId(profileId) {
40
+ const normalized = (profileId || DEFAULT_PROFILE_ID).trim();
41
+ if (!/^[a-z0-9][a-z0-9._-]{0,62}$/u.test(normalized)) {
42
+ throw new W3KitsStorageError("invalid_profile_id", "Invalid profile id");
43
+ }
44
+ if (normalized === "." || normalized === "..") {
45
+ throw new W3KitsStorageError("invalid_profile_id", "Invalid profile id");
46
+ }
47
+ return normalized;
48
+ }
49
+ /**
50
+ * Normalizes plugin slugs used in .app and config roots.
51
+ */
52
+ export function normalizePluginSlug(pluginSlug) {
53
+ const normalized = pluginSlug.trim();
54
+ if (!/^[a-z0-9][a-z0-9._-]{0,127}$/u.test(normalized)) {
55
+ throw new W3KitsStorageError("invalid_plugin_slug", "Invalid plugin slug");
56
+ }
57
+ return normalized;
58
+ }
59
+ /**
60
+ * Normalizes a root-relative path without allowing escape segments.
61
+ */
62
+ export function normalizeRelativePath(input) {
63
+ const raw = input.trim().replace(/\\/g, "/").replace(/^\/+/, "");
64
+ if (CONTROL_CHARS.test(raw)) {
65
+ throw new W3KitsStorageError("invalid_visible_path", "Visible path contains unsupported characters");
66
+ }
67
+ const segments = [];
68
+ for (const segment of raw.split("/")) {
69
+ if (!segment || segment === ".")
70
+ continue;
71
+ if (segment === "..") {
72
+ throw new W3KitsStorageError("path_escape", "Visible path cannot escape its root");
73
+ }
74
+ segments.push(segment);
75
+ }
76
+ return segments.join("/");
77
+ }
78
+ /**
79
+ * Converts a visible /home/agent path to a normalized relative home path.
80
+ */
81
+ export function visiblePathToHomeRelative(visiblePath) {
82
+ const raw = visiblePath.trim().replace(/\\/g, "/").replace(/\/+$/u, "");
83
+ if (raw === "" ||
84
+ raw === "/" ||
85
+ raw === "/home" ||
86
+ raw === VISIBLE_HOME_ROOT) {
87
+ return "";
88
+ }
89
+ if (!raw.startsWith(`${VISIBLE_HOME_ROOT}/`)) {
90
+ throw new W3KitsStorageError("outside_visible_root", `Visible path must be under ${VISIBLE_HOME_ROOT}`);
91
+ }
92
+ return normalizeRelativePath(raw.slice(`${VISIBLE_HOME_ROOT}/`.length));
93
+ }
94
+ /**
95
+ * Converts a relative home path back to the visible path contract.
96
+ */
97
+ export function homeRelativeToVisiblePath(relativeHomePath) {
98
+ const relative = normalizeRelativePath(relativeHomePath);
99
+ return relative ? `${VISIBLE_HOME_ROOT}/${relative}` : VISIBLE_HOME_ROOT;
100
+ }
101
+ /**
102
+ * Builds the R2 key for a visible /home/agent path.
103
+ */
104
+ export function visiblePathToR2Key(visiblePath, scope) {
105
+ const userId = normalizeUserId(scope.userId);
106
+ const profileId = normalizeProfileId(scope.profileId);
107
+ const relativeHomePath = visiblePathToHomeRelative(visiblePath);
108
+ return ["users", userId, "profiles", profileId, "home", relativeHomePath]
109
+ .filter((segment) => segment !== "")
110
+ .join("/");
111
+ }
112
+ /**
113
+ * Returns all mapping components for a visible /home/agent path.
114
+ */
115
+ export function mapVisiblePathToR2(visiblePath, scope) {
116
+ const userId = normalizeUserId(scope.userId);
117
+ const profileId = normalizeProfileId(scope.profileId);
118
+ const relativeHomePath = visiblePathToHomeRelative(visiblePath);
119
+ return {
120
+ userId,
121
+ profileId,
122
+ visiblePath: homeRelativeToVisiblePath(relativeHomePath),
123
+ relativeHomePath,
124
+ r2Key: ["users", userId, "profiles", profileId, "home", relativeHomePath]
125
+ .filter((segment) => segment !== "")
126
+ .join("/"),
127
+ };
128
+ }
129
+ /**
130
+ * Builds a plugin config root under /home/agent.
131
+ */
132
+ export function pluginConfigRoot(pluginSlug) {
133
+ return `${VISIBLE_HOME_ROOT}/.config/${normalizePluginSlug(pluginSlug)}`;
134
+ }
135
+ /**
136
+ * Builds the target .app path for installed plugin launchers.
137
+ */
138
+ export function appFilePath(pluginSlug) {
139
+ return `${APPLICATIONS_ROOT}/${normalizePluginSlug(pluginSlug)}.app`;
140
+ }
141
+ /**
142
+ * Creates a conflict-copy path under the same visible directory.
143
+ */
144
+ export function conflictCopyVisiblePath(visiblePath, input = {}) {
145
+ const normalized = homeRelativeToVisiblePath(visiblePathToHomeRelative(visiblePath));
146
+ const slash = normalized.lastIndexOf("/");
147
+ const directory = slash >= 0 ? normalized.slice(0, slash) : VISIBLE_HOME_ROOT;
148
+ const filename = slash >= 0 ? normalized.slice(slash + 1) : normalized;
149
+ const dot = filename.lastIndexOf(".");
150
+ const stem = dot > 0 ? filename.slice(0, dot) : filename;
151
+ const extension = dot > 0 ? filename.slice(dot) : "";
152
+ const stamp = input.label ??
153
+ (input.now ?? new Date()).toISOString().replace(/[:.]/g, "-");
154
+ return `${directory}/${stem}.conflict-${stamp}${extension}`;
155
+ }
156
+ //# sourceMappingURL=path-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-mapping.js","sourceRoot":"","sources":["../src/path-mapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type R2DataPlaneDescriptor, type W3KitsStorageCapabilityDescriptor } from "./r2-client.js";
2
+ export * from "./path-mapping.js";
3
+ export * from "./local-cache.js";
4
+ export * from "./app-file.js";
5
+ export * from "./storage/index.js";
6
+ export * from "./r2-client.js";
7
+ export type W3KitsPluginStorage = {
8
+ descriptor: W3KitsStorageCapabilityDescriptor;
9
+ visibleRoot: W3KitsStorageCapabilityDescriptor["visibleRoot"];
10
+ capability: W3KitsStorageCapabilityDescriptor["capability"];
11
+ r2: R2DataPlaneDescriptor;
12
+ authHeader: "x-w3kits-runtime-session";
13
+ localFirst: W3KitsStorageCapabilityDescriptor["localFirst"];
14
+ r2KeyForVisiblePath(visiblePath: string): string;
15
+ };
16
+ export type InitializeW3KitsPluginStorageInput = {
17
+ descriptor: unknown;
18
+ expectedPluginSlug?: string;
19
+ };
20
+ /**
21
+ * Represents plugin storage descriptor validation failures.
22
+ */
23
+ export declare class W3KitsPluginStorageError extends Error {
24
+ readonly code: "legacy_storage_descriptor" | "invalid_storage_descriptor" | "invalid_storage_descriptor_version" | "legacy_fake_credentials" | "permanent_r2_credentials" | "descriptor_scope_mismatch" | "path_outside_capability";
25
+ /**
26
+ * Initializes a plugin storage error with a stable code.
27
+ */
28
+ constructor(code: "legacy_storage_descriptor" | "invalid_storage_descriptor" | "invalid_storage_descriptor_version" | "legacy_fake_credentials" | "permanent_r2_credentials" | "descriptor_scope_mismatch" | "path_outside_capability", message: string);
29
+ }
30
+ /**
31
+ * Validates and initializes the plugin storage bridge from a Core-issued descriptor.
32
+ */
33
+ export declare function initializeW3KitsPluginStorage(input: InitializeW3KitsPluginStorageInput): W3KitsPluginStorage;
34
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,iCAAiC,EACvC,MAAM,gBAAgB,CAAC;AAIxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAE/B,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,iCAAiC,CAAC;IAC9C,WAAW,EAAE,iCAAiC,CAAC,aAAa,CAAC,CAAC;IAC9D,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;IAC5D,EAAE,EAAE,qBAAqB,CAAC;IAC1B,UAAU,EAAE,0BAA0B,CAAC;IACvC,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;IAC5D,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;aAK/B,IAAI,EAChB,2BAA2B,GAC3B,4BAA4B,GAC5B,oCAAoC,GACpC,yBAAyB,GACzB,0BAA0B,GAC1B,2BAA2B,GAC3B,yBAAyB;IAX/B;;OAEG;gBAEe,IAAI,EAChB,2BAA2B,GAC3B,4BAA4B,GAC5B,oCAAoC,GACpC,yBAAyB,GACzB,0BAA0B,GAC1B,2BAA2B,GAC3B,yBAAyB,EAC7B,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,kCAAkC,GACxC,mBAAmB,CA0CrB"}
package/dist/plugin.js ADDED
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Plugin SDK entrypoint.
3
+ * @owner w3kits-sdk
4
+ * @module sdk
5
+ */
6
+ import { mapVisiblePathToR2, pluginConfigRoot, } from "./path-mapping.js";
7
+ import { W3KITS_STORAGE_CAPABILITY_DESCRIPTOR_VERSION, } from "./r2-client.js";
8
+ const LEGACY_OBJECT_FACADE_PATH = `/${["api", "vfs", "objects"].join("/")}`;
9
+ export * from "./path-mapping.js";
10
+ export * from "./local-cache.js";
11
+ export * from "./app-file.js";
12
+ export * from "./storage/index.js";
13
+ export * from "./r2-client.js";
14
+ /**
15
+ * Represents plugin storage descriptor validation failures.
16
+ */
17
+ export class W3KitsPluginStorageError extends Error {
18
+ code;
19
+ /**
20
+ * Initializes a plugin storage error with a stable code.
21
+ */
22
+ constructor(code, message) {
23
+ super(message);
24
+ this.code = code;
25
+ this.name = "W3KitsPluginStorageError";
26
+ }
27
+ }
28
+ /**
29
+ * Validates and initializes the plugin storage bridge from a Core-issued descriptor.
30
+ */
31
+ export function initializeW3KitsPluginStorage(input) {
32
+ const descriptor = assertW3KitsStorageCapabilityDescriptor(input.descriptor);
33
+ if (input.expectedPluginSlug &&
34
+ descriptor.visibleRoot !== pluginConfigRoot(input.expectedPluginSlug)) {
35
+ throw new W3KitsPluginStorageError("descriptor_scope_mismatch", "Plugin storage descriptor is not scoped to this plugin config root");
36
+ }
37
+ const expectedPrefix = mapVisiblePathToR2(descriptor.visibleRoot, {
38
+ userId: descriptor.capability.userId,
39
+ profileId: descriptor.capability.profileId,
40
+ }).r2Key;
41
+ if (descriptor.r2.prefix !== expectedPrefix) {
42
+ throw new W3KitsPluginStorageError("descriptor_scope_mismatch", "Plugin storage descriptor R2 prefix does not match its visible root");
43
+ }
44
+ return {
45
+ descriptor,
46
+ visibleRoot: descriptor.visibleRoot,
47
+ capability: descriptor.capability,
48
+ r2: descriptor.r2,
49
+ authHeader: descriptor.auth.header,
50
+ localFirst: descriptor.localFirst,
51
+ r2KeyForVisiblePath(visiblePath) {
52
+ const mapping = mapVisiblePathToR2(visiblePath, descriptor.capability);
53
+ if (!r2KeyWithinPrefix(mapping.r2Key, descriptor.r2.prefix)) {
54
+ throw new W3KitsPluginStorageError("path_outside_capability", "Visible path is outside the plugin storage capability");
55
+ }
56
+ return mapping.r2Key;
57
+ },
58
+ };
59
+ }
60
+ /**
61
+ * Asserts that an unknown value is a current SDK storage capability descriptor.
62
+ */
63
+ function assertW3KitsStorageCapabilityDescriptor(value) {
64
+ const descriptor = record(value, "invalid_storage_descriptor");
65
+ if (descriptor.type === "w3kits-vfs-object-facade" ||
66
+ descriptor.endpoint === LEGACY_OBJECT_FACADE_PATH) {
67
+ throw new W3KitsPluginStorageError("legacy_storage_descriptor", "Legacy VFS object-facade descriptors are not accepted by the SDK plugin bridge");
68
+ }
69
+ if (descriptor.version !== W3KITS_STORAGE_CAPABILITY_DESCRIPTOR_VERSION) {
70
+ throw new W3KitsPluginStorageError("invalid_storage_descriptor_version", "Unsupported W3Kits storage descriptor version");
71
+ }
72
+ const capability = record(descriptor.capability, "invalid_storage_descriptor");
73
+ const r2 = record(descriptor.r2, "invalid_storage_descriptor");
74
+ const auth = record(descriptor.auth, "invalid_storage_descriptor");
75
+ const localFirst = record(descriptor.localFirst, "invalid_storage_descriptor");
76
+ if (typeof descriptor.visibleRoot !== "string" ||
77
+ descriptor.visibleRoot !== capability.root ||
78
+ typeof capability.userId !== "string" ||
79
+ typeof capability.profileId !== "string" ||
80
+ !Array.isArray(capability.actions) ||
81
+ typeof capability.expiresAt !== "string" ||
82
+ typeof capability.credentialMode !== "string" ||
83
+ typeof r2.bucket !== "string" ||
84
+ typeof r2.endpoint !== "string" ||
85
+ r2.region !== "auto" ||
86
+ r2.forcePathStyle !== true ||
87
+ typeof r2.prefix !== "string" ||
88
+ !Array.isArray(r2.actions) ||
89
+ auth.mode !== "runtime-session" ||
90
+ auth.header !== "x-w3kits-runtime-session" ||
91
+ typeof localFirst.enabled !== "boolean") {
92
+ throw new W3KitsPluginStorageError("invalid_storage_descriptor", "Invalid W3Kits storage capability descriptor");
93
+ }
94
+ if (r2.credentials !== undefined) {
95
+ const credentials = record(r2.credentials, "invalid_storage_descriptor");
96
+ if (credentials.accessKeyId === "w3kits" ||
97
+ credentials.secretAccessKey === "w3kits-runtime-session") {
98
+ throw new W3KitsPluginStorageError("legacy_fake_credentials", "Legacy fake S3 credentials are not accepted by the SDK plugin bridge");
99
+ }
100
+ if (typeof credentials.accessKeyId !== "string" ||
101
+ typeof credentials.secretAccessKey !== "string" ||
102
+ typeof credentials.expiresAt !== "string") {
103
+ throw new W3KitsPluginStorageError("permanent_r2_credentials", "Plugin storage descriptors may only include expiring R2 credentials");
104
+ }
105
+ }
106
+ return descriptor;
107
+ }
108
+ /**
109
+ * Narrows an unknown descriptor fragment to a non-array object.
110
+ */
111
+ function record(value, code) {
112
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
113
+ throw new W3KitsPluginStorageError(code, "Invalid W3Kits plugin storage descriptor");
114
+ }
115
+ return value;
116
+ }
117
+ /**
118
+ * Checks whether a mapped R2 key remains inside the descriptor prefix.
119
+ */
120
+ function r2KeyWithinPrefix(key, prefix) {
121
+ const cleanPrefix = prefix.replace(/\/+$/u, "");
122
+ return key === cleanPrefix || key.startsWith(`${cleanPrefix}/`);
123
+ }
124
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}