@syncular/server-storage-filesystem 0.0.6-158 → 0.0.6-165

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/dist/index.d.ts CHANGED
@@ -9,7 +9,14 @@ import type { BlobStorageAdapter } from '@syncular/core';
9
9
  export interface BlobTokenSigner {
10
10
  sign(payload: {
11
11
  hash: string;
12
- action: 'upload' | 'download';
12
+ partitionId: string;
13
+ action: 'upload';
14
+ size: number;
15
+ expiresAt: number;
16
+ } | {
17
+ hash: string;
18
+ partitionId: string;
19
+ action: 'download';
13
20
  expiresAt: number;
14
21
  }, expiresInSeconds: number): Promise<string>;
15
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,eAAe;IAC9B,IAAI,CACF,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;KACnB,EACD,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAOD,MAAM,WAAW,mCAAmC;IAClD,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,WAAW,EAAE,eAAe,CAAC;CAC9B;AAeD;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,mCAAmC,GAC3C,kBAAkB,CA8HpB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,eAAe;IAC9B,IAAI,CACF,OAAO,EACH;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,QAAQ,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,GACD;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,UAAU,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,EACL,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC;CACpB;AAOD,MAAM,WAAW,mCAAmC;IAClD,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,WAAW,EAAE,eAAe,CAAC;CAC9B;AA8BD;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,mCAAmC,GAC3C,kBAAkB,CAgKpB"}
package/dist/index.js CHANGED
@@ -16,9 +16,20 @@ function hasErrnoCode(error, code) {
16
16
  * Resolve hash to a 2-level subdirectory path:
17
17
  * `{basePath}/{hex[0..2]}/{hex[2..4]}/{hex}`
18
18
  */
19
- function hashToFilePath(basePath, hash) {
19
+ function normalizePartitionId(partitionId) {
20
+ const raw = partitionId?.trim();
21
+ if (!raw)
22
+ return 'default';
23
+ return raw;
24
+ }
25
+ function hashToFilePath(basePath, hash, partitionId) {
20
26
  const hex = hash.startsWith('sha256:') ? hash.slice(7) : hash;
21
- return join(basePath, hex.slice(0, 2), hex.slice(2, 4), hex);
27
+ const normalizedPartition = normalizePartitionId(partitionId);
28
+ if (!partitionId || normalizedPartition === 'default') {
29
+ return join(basePath, hex.slice(0, 2), hex.slice(2, 4), hex);
30
+ }
31
+ const partitionPath = encodeURIComponent(normalizedPartition);
32
+ return join(basePath, partitionPath, hex.slice(0, 2), hex.slice(2, 4), hex);
22
33
  }
23
34
  function tmpPath(filePath) {
24
35
  return `${filePath}.${Date.now()}.tmp`;
@@ -41,8 +52,15 @@ export function createFilesystemBlobStorageAdapter(options) {
41
52
  return {
42
53
  name: 'filesystem',
43
54
  async signUpload(opts) {
55
+ const partitionId = normalizePartitionId(opts.partitionId);
44
56
  const expiresAt = Date.now() + opts.expiresIn * 1000;
45
- const token = await tokenSigner.sign({ hash: opts.hash, action: 'upload', expiresAt }, opts.expiresIn);
57
+ const token = await tokenSigner.sign({
58
+ hash: opts.hash,
59
+ partitionId,
60
+ action: 'upload',
61
+ size: opts.size,
62
+ expiresAt,
63
+ }, opts.expiresIn);
46
64
  const url = `${normalizedBaseUrl}/blobs/${encodeURIComponent(opts.hash)}/upload?token=${encodeURIComponent(token)}`;
47
65
  return {
48
66
  url,
@@ -54,46 +72,47 @@ export function createFilesystemBlobStorageAdapter(options) {
54
72
  };
55
73
  },
56
74
  async signDownload(opts) {
75
+ const partitionId = normalizePartitionId(opts.partitionId);
57
76
  const expiresAt = Date.now() + opts.expiresIn * 1000;
58
- const token = await tokenSigner.sign({ hash: opts.hash, action: 'download', expiresAt }, opts.expiresIn);
77
+ const token = await tokenSigner.sign({ hash: opts.hash, partitionId, action: 'download', expiresAt }, opts.expiresIn);
59
78
  return `${normalizedBaseUrl}/blobs/${encodeURIComponent(opts.hash)}/download?token=${encodeURIComponent(token)}`;
60
79
  },
61
- async exists(hash) {
80
+ async exists(hash, options) {
62
81
  try {
63
- await stat(hashToFilePath(basePath, hash));
82
+ await stat(hashToFilePath(basePath, hash, options?.partitionId));
64
83
  return true;
65
84
  }
66
85
  catch {
67
86
  return false;
68
87
  }
69
88
  },
70
- async delete(hash) {
89
+ async delete(hash, options) {
71
90
  try {
72
- await unlink(hashToFilePath(basePath, hash));
91
+ await unlink(hashToFilePath(basePath, hash, options?.partitionId));
73
92
  }
74
93
  catch (err) {
75
94
  if (!hasErrnoCode(err, 'ENOENT'))
76
95
  throw err;
77
96
  }
78
97
  },
79
- async getMetadata(hash) {
98
+ async getMetadata(hash, options) {
80
99
  try {
81
- const fileStats = await stat(hashToFilePath(basePath, hash));
100
+ const fileStats = await stat(hashToFilePath(basePath, hash, options?.partitionId));
82
101
  return { size: fileStats.size };
83
102
  }
84
103
  catch {
85
104
  return null;
86
105
  }
87
106
  },
88
- async put(hash, data) {
89
- const filePath = hashToFilePath(basePath, hash);
107
+ async put(hash, data, _metadata, options) {
108
+ const filePath = hashToFilePath(basePath, hash, options?.partitionId);
90
109
  const tmp = tmpPath(filePath);
91
110
  await mkdir(dirname(filePath), { recursive: true });
92
111
  await writeFile(tmp, data);
93
112
  await rename(tmp, filePath);
94
113
  },
95
- async putStream(hash, stream) {
96
- const filePath = hashToFilePath(basePath, hash);
114
+ async putStream(hash, stream, _metadata, options) {
115
+ const filePath = hashToFilePath(basePath, hash, options?.partitionId);
97
116
  const tmp = tmpPath(filePath);
98
117
  await mkdir(dirname(filePath), { recursive: true });
99
118
  const fh = await open(tmp, 'w');
@@ -111,9 +130,9 @@ export function createFilesystemBlobStorageAdapter(options) {
111
130
  }
112
131
  await rename(tmp, filePath);
113
132
  },
114
- async get(hash) {
133
+ async get(hash, options) {
115
134
  try {
116
- const data = await readFile(hashToFilePath(basePath, hash));
135
+ const data = await readFile(hashToFilePath(basePath, hash, options?.partitionId));
117
136
  return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
118
137
  }
119
138
  catch (err) {
@@ -122,10 +141,10 @@ export function createFilesystemBlobStorageAdapter(options) {
122
141
  throw err;
123
142
  }
124
143
  },
125
- async getStream(hash) {
144
+ async getStream(hash, options) {
126
145
  let data;
127
146
  try {
128
- data = await readFile(hashToFilePath(basePath, hash));
147
+ data = await readFile(hashToFilePath(basePath, hash, options?.partitionId));
129
148
  }
130
149
  catch (err) {
131
150
  if (hasErrnoCode(err, 'ENOENT'))
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/server-storage-filesystem",
3
- "version": "0.0.6-158",
3
+ "version": "0.0.6-165",
4
4
  "description": "Filesystem blob storage adapter for Syncular server",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
@@ -41,11 +41,11 @@
41
41
  "release": "bunx syncular-publish"
42
42
  },
43
43
  "dependencies": {
44
- "@syncular/core": "0.0.6-158"
44
+ "@syncular/core": "0.0.6-165"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@syncular/config": "0.0.0",
48
- "@syncular/server": "0.0.6-158"
48
+ "@syncular/server": "0.0.6-165"
49
49
  },
50
50
  "files": [
51
51
  "dist",
package/src/index.ts CHANGED
@@ -25,11 +25,20 @@ import type {
25
25
 
26
26
  export interface BlobTokenSigner {
27
27
  sign(
28
- payload: {
29
- hash: string;
30
- action: 'upload' | 'download';
31
- expiresAt: number;
32
- },
28
+ payload:
29
+ | {
30
+ hash: string;
31
+ partitionId: string;
32
+ action: 'upload';
33
+ size: number;
34
+ expiresAt: number;
35
+ }
36
+ | {
37
+ hash: string;
38
+ partitionId: string;
39
+ action: 'download';
40
+ expiresAt: number;
41
+ },
33
42
  expiresInSeconds: number
34
43
  ): Promise<string>;
35
44
  }
@@ -52,9 +61,24 @@ export interface FilesystemBlobStorageAdapterOptions {
52
61
  * Resolve hash to a 2-level subdirectory path:
53
62
  * `{basePath}/{hex[0..2]}/{hex[2..4]}/{hex}`
54
63
  */
55
- function hashToFilePath(basePath: string, hash: string): string {
64
+ function normalizePartitionId(partitionId?: string): string {
65
+ const raw = partitionId?.trim();
66
+ if (!raw) return 'default';
67
+ return raw;
68
+ }
69
+
70
+ function hashToFilePath(
71
+ basePath: string,
72
+ hash: string,
73
+ partitionId?: string
74
+ ): string {
56
75
  const hex = hash.startsWith('sha256:') ? hash.slice(7) : hash;
57
- return join(basePath, hex.slice(0, 2), hex.slice(2, 4), hex);
76
+ const normalizedPartition = normalizePartitionId(partitionId);
77
+ if (!partitionId || normalizedPartition === 'default') {
78
+ return join(basePath, hex.slice(0, 2), hex.slice(2, 4), hex);
79
+ }
80
+ const partitionPath = encodeURIComponent(normalizedPartition);
81
+ return join(basePath, partitionPath, hex.slice(0, 2), hex.slice(2, 4), hex);
58
82
  }
59
83
 
60
84
  function tmpPath(filePath: string): string {
@@ -83,9 +107,16 @@ export function createFilesystemBlobStorageAdapter(
83
107
  name: 'filesystem',
84
108
 
85
109
  async signUpload(opts: BlobSignUploadOptions): Promise<BlobSignedUpload> {
110
+ const partitionId = normalizePartitionId(opts.partitionId);
86
111
  const expiresAt = Date.now() + opts.expiresIn * 1000;
87
112
  const token = await tokenSigner.sign(
88
- { hash: opts.hash, action: 'upload', expiresAt },
113
+ {
114
+ hash: opts.hash,
115
+ partitionId,
116
+ action: 'upload',
117
+ size: opts.size,
118
+ expiresAt,
119
+ },
89
120
  opts.expiresIn
90
121
  );
91
122
 
@@ -102,45 +133,60 @@ export function createFilesystemBlobStorageAdapter(
102
133
  },
103
134
 
104
135
  async signDownload(opts: BlobSignDownloadOptions): Promise<string> {
136
+ const partitionId = normalizePartitionId(opts.partitionId);
105
137
  const expiresAt = Date.now() + opts.expiresIn * 1000;
106
138
  const token = await tokenSigner.sign(
107
- { hash: opts.hash, action: 'download', expiresAt },
139
+ { hash: opts.hash, partitionId, action: 'download', expiresAt },
108
140
  opts.expiresIn
109
141
  );
110
142
 
111
143
  return `${normalizedBaseUrl}/blobs/${encodeURIComponent(opts.hash)}/download?token=${encodeURIComponent(token)}`;
112
144
  },
113
145
 
114
- async exists(hash: string): Promise<boolean> {
146
+ async exists(
147
+ hash: string,
148
+ options?: { partitionId?: string }
149
+ ): Promise<boolean> {
115
150
  try {
116
- await stat(hashToFilePath(basePath, hash));
151
+ await stat(hashToFilePath(basePath, hash, options?.partitionId));
117
152
  return true;
118
153
  } catch {
119
154
  return false;
120
155
  }
121
156
  },
122
157
 
123
- async delete(hash: string): Promise<void> {
158
+ async delete(
159
+ hash: string,
160
+ options?: { partitionId?: string }
161
+ ): Promise<void> {
124
162
  try {
125
- await unlink(hashToFilePath(basePath, hash));
163
+ await unlink(hashToFilePath(basePath, hash, options?.partitionId));
126
164
  } catch (err) {
127
165
  if (!hasErrnoCode(err, 'ENOENT')) throw err;
128
166
  }
129
167
  },
130
168
 
131
169
  async getMetadata(
132
- hash: string
170
+ hash: string,
171
+ options?: { partitionId?: string }
133
172
  ): Promise<{ size: number; mimeType?: string } | null> {
134
173
  try {
135
- const fileStats = await stat(hashToFilePath(basePath, hash));
174
+ const fileStats = await stat(
175
+ hashToFilePath(basePath, hash, options?.partitionId)
176
+ );
136
177
  return { size: fileStats.size };
137
178
  } catch {
138
179
  return null;
139
180
  }
140
181
  },
141
182
 
142
- async put(hash: string, data: Uint8Array): Promise<void> {
143
- const filePath = hashToFilePath(basePath, hash);
183
+ async put(
184
+ hash: string,
185
+ data: Uint8Array,
186
+ _metadata?: Record<string, unknown>,
187
+ options?: { partitionId?: string }
188
+ ): Promise<void> {
189
+ const filePath = hashToFilePath(basePath, hash, options?.partitionId);
144
190
  const tmp = tmpPath(filePath);
145
191
  await mkdir(dirname(filePath), { recursive: true });
146
192
  await writeFile(tmp, data);
@@ -149,9 +195,11 @@ export function createFilesystemBlobStorageAdapter(
149
195
 
150
196
  async putStream(
151
197
  hash: string,
152
- stream: ReadableStream<Uint8Array>
198
+ stream: ReadableStream<Uint8Array>,
199
+ _metadata?: Record<string, unknown>,
200
+ options?: { partitionId?: string }
153
201
  ): Promise<void> {
154
- const filePath = hashToFilePath(basePath, hash);
202
+ const filePath = hashToFilePath(basePath, hash, options?.partitionId);
155
203
  const tmp = tmpPath(filePath);
156
204
  await mkdir(dirname(filePath), { recursive: true });
157
205
 
@@ -170,9 +218,14 @@ export function createFilesystemBlobStorageAdapter(
170
218
  await rename(tmp, filePath);
171
219
  },
172
220
 
173
- async get(hash: string): Promise<Uint8Array | null> {
221
+ async get(
222
+ hash: string,
223
+ options?: { partitionId?: string }
224
+ ): Promise<Uint8Array | null> {
174
225
  try {
175
- const data = await readFile(hashToFilePath(basePath, hash));
226
+ const data = await readFile(
227
+ hashToFilePath(basePath, hash, options?.partitionId)
228
+ );
176
229
  return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
177
230
  } catch (err) {
178
231
  if (hasErrnoCode(err, 'ENOENT')) return null;
@@ -180,10 +233,15 @@ export function createFilesystemBlobStorageAdapter(
180
233
  }
181
234
  },
182
235
 
183
- async getStream(hash: string): Promise<ReadableStream<Uint8Array> | null> {
236
+ async getStream(
237
+ hash: string,
238
+ options?: { partitionId?: string }
239
+ ): Promise<ReadableStream<Uint8Array> | null> {
184
240
  let data: Uint8Array;
185
241
  try {
186
- data = await readFile(hashToFilePath(basePath, hash));
242
+ data = await readFile(
243
+ hashToFilePath(basePath, hash, options?.partitionId)
244
+ );
187
245
  } catch (err) {
188
246
  if (hasErrnoCode(err, 'ENOENT')) return null;
189
247
  throw err;