@toa.io/extensions.storages 1.0.0-alpha.34 → 1.0.0-alpha.340

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 (122) hide show
  1. package/package.json +43 -18
  2. package/readme.md +127 -47
  3. package/transpiled/Aspect.d.ts +8 -4
  4. package/transpiled/Aspect.js +12 -14
  5. package/transpiled/Aspect.js.map +1 -1
  6. package/transpiled/Entry.d.ts +14 -11
  7. package/transpiled/Entry.js +1 -2
  8. package/transpiled/Factory.d.ts +10 -2
  9. package/transpiled/Factory.js +52 -32
  10. package/transpiled/Factory.js.map +1 -1
  11. package/transpiled/Provider.d.ts +23 -19
  12. package/transpiled/Provider.js +18 -32
  13. package/transpiled/Provider.js.map +1 -1
  14. package/transpiled/Scanner.d.ts +10 -4
  15. package/transpiled/Scanner.js +38 -26
  16. package/transpiled/Scanner.js.map +1 -1
  17. package/transpiled/Secrets.d.ts +5 -0
  18. package/transpiled/Secrets.js +2 -0
  19. package/transpiled/Secrets.js.map +1 -0
  20. package/transpiled/Storage.d.ts +35 -22
  21. package/transpiled/Storage.js +95 -141
  22. package/transpiled/Storage.js.map +1 -1
  23. package/transpiled/errors.d.ts +15 -0
  24. package/transpiled/errors.js +12 -0
  25. package/transpiled/errors.js.map +1 -0
  26. package/transpiled/index.d.ts +4 -4
  27. package/transpiled/index.js +1 -9
  28. package/transpiled/index.js.map +1 -1
  29. package/transpiled/measurements.d.ts +3 -0
  30. package/transpiled/measurements.js +23 -0
  31. package/transpiled/measurements.js.map +1 -0
  32. package/transpiled/providers/Cloudinary.d.ts +55 -0
  33. package/transpiled/providers/Cloudinary.js +232 -0
  34. package/transpiled/providers/Cloudinary.js.map +1 -0
  35. package/transpiled/providers/Declaration.d.ts +9 -5
  36. package/transpiled/providers/Declaration.js +1 -2
  37. package/transpiled/providers/FileSystem.d.ts +16 -11
  38. package/transpiled/providers/FileSystem.js +64 -43
  39. package/transpiled/providers/FileSystem.js.map +1 -1
  40. package/transpiled/providers/S3.d.ts +18 -18
  41. package/transpiled/providers/S3.js +87 -122
  42. package/transpiled/providers/S3.js.map +1 -1
  43. package/transpiled/providers/Spaces.d.ts +12 -0
  44. package/transpiled/providers/Spaces.js +13 -0
  45. package/transpiled/providers/Spaces.js.map +1 -0
  46. package/transpiled/providers/Temporary.d.ts +2 -3
  47. package/transpiled/providers/Temporary.js +7 -11
  48. package/transpiled/providers/Temporary.js.map +1 -1
  49. package/transpiled/providers/Test.d.ts +4 -4
  50. package/transpiled/providers/Test.js +6 -12
  51. package/transpiled/providers/Test.js.map +1 -1
  52. package/transpiled/providers/index.d.ts +23 -11
  53. package/transpiled/providers/index.js +30 -14
  54. package/transpiled/providers/index.js.map +1 -1
  55. package/transpiled/providers/index.types.d.ts +5 -0
  56. package/transpiled/providers/index.types.js +2 -0
  57. package/transpiled/providers/index.types.js.map +1 -0
  58. package/transpiled/test/util.d.ts +113 -6
  59. package/transpiled/test/util.js +68 -15
  60. package/transpiled/test/util.js.map +1 -1
  61. package/schemas/annotation.cos.yaml +0 -10
  62. package/schemas/fs.cos.yaml +0 -9
  63. package/schemas/mem.cos.yaml +0 -6
  64. package/schemas/s3.cos.yaml +0 -16
  65. package/schemas/test.cos.yaml +0 -8
  66. package/schemas/tmp.cos.yaml +0 -9
  67. package/source/Annotation.ts +0 -39
  68. package/source/Aspect.ts +0 -25
  69. package/source/Entry.ts +0 -14
  70. package/source/Factory.ts +0 -68
  71. package/source/Provider.ts +0 -37
  72. package/source/Scanner.ts +0 -153
  73. package/source/Storage.test.ts +0 -472
  74. package/source/Storage.ts +0 -235
  75. package/source/deployment.ts +0 -57
  76. package/source/index.ts +0 -5
  77. package/source/manifest.ts +0 -8
  78. package/source/providers/Declaration.ts +0 -10
  79. package/source/providers/FileSystem.test.ts +0 -5
  80. package/source/providers/FileSystem.ts +0 -63
  81. package/source/providers/Memory.ts +0 -55
  82. package/source/providers/S3.test.ts +0 -134
  83. package/source/providers/S3.ts +0 -196
  84. package/source/providers/Temporary.ts +0 -16
  85. package/source/providers/Test.ts +0 -13
  86. package/source/providers/index.test.ts +0 -136
  87. package/source/providers/index.ts +0 -16
  88. package/source/providers/readme.md +0 -25
  89. package/source/schemas.test.ts +0 -58
  90. package/source/schemas.ts +0 -15
  91. package/source/test/.env.example +0 -1
  92. package/source/test/albert.jpg +0 -0
  93. package/source/test/empty.txt +0 -0
  94. package/source/test/lenna.ascii +0 -64
  95. package/source/test/lenna.png +0 -0
  96. package/source/test/sample.avi +0 -0
  97. package/source/test/sample.avif +0 -0
  98. package/source/test/sample.gif +0 -0
  99. package/source/test/sample.heic +0 -0
  100. package/source/test/sample.jpeg +0 -0
  101. package/source/test/sample.jxl +0 -0
  102. package/source/test/sample.svg +0 -4
  103. package/source/test/sample.wav +0 -0
  104. package/source/test/sample.webp +0 -0
  105. package/source/test/util.ts +0 -45
  106. package/transpiled/Annotation.d.ts +0 -3
  107. package/transpiled/Annotation.js +0 -57
  108. package/transpiled/Annotation.js.map +0 -1
  109. package/transpiled/deployment.d.ts +0 -5
  110. package/transpiled/deployment.js +0 -68
  111. package/transpiled/deployment.js.map +0 -1
  112. package/transpiled/manifest.d.ts +0 -1
  113. package/transpiled/manifest.js +0 -9
  114. package/transpiled/manifest.js.map +0 -1
  115. package/transpiled/providers/Memory.d.ts +0 -15
  116. package/transpiled/providers/Memory.js +0 -72
  117. package/transpiled/providers/Memory.js.map +0 -1
  118. package/transpiled/schemas.d.ts +0 -9
  119. package/transpiled/schemas.js +0 -14
  120. package/transpiled/schemas.js.map +0 -1
  121. package/transpiled/tsconfig.tsbuildinfo +0 -1
  122. package/tsconfig.json +0 -12
@@ -0,0 +1,15 @@
1
+ /**
2
+ * An error a storage answers with. Its message is its code, so an operation that returns it
3
+ * refuses with that code, and it carries the code as a call's error does, so whoever asked
4
+ * the storage reads it the same way.
5
+ */
6
+ export declare function coded(code: string): Error & {
7
+ code: string;
8
+ };
9
+ export declare const ERR_NOT_FOUND: Error & {
10
+ code: string;
11
+ };
12
+ /** The storage serves no address of its own: what it holds is reached through it alone. */
13
+ export declare const ERR_NO_URL: Error & {
14
+ code: string;
15
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * An error a storage answers with. Its message is its code, so an operation that returns it
3
+ * refuses with that code, and it carries the code as a call's error does, so whoever asked
4
+ * the storage reads it the same way.
5
+ */
6
+ export function coded(code) {
7
+ return Object.assign(new Error(code), { code });
8
+ }
9
+ export const ERR_NOT_FOUND = coded('NOT_FOUND');
10
+ /** The storage serves no address of its own: what it holds is reached through it alone. */
11
+ export const ERR_NO_URL = coded('NO_URL');
12
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../source/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;AAE/C,2FAA2F;AAC3F,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA"}
@@ -1,4 +1,4 @@
1
- export { Factory } from './Factory';
2
- export { deployment } from './deployment';
3
- export { manifest } from './manifest';
4
- export type { Entry } from './Entry';
1
+ export { Factory } from './Factory.ts';
2
+ export type { Entry, Stream } from './Entry.ts';
3
+ export type { Storage, UrlOptions } from './Storage.ts';
4
+ export type * from './providers/index.ts';
@@ -1,10 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.manifest = exports.deployment = exports.Factory = void 0;
4
- var Factory_1 = require("./Factory");
5
- Object.defineProperty(exports, "Factory", { enumerable: true, get: function () { return Factory_1.Factory; } });
6
- var deployment_1 = require("./deployment");
7
- Object.defineProperty(exports, "deployment", { enumerable: true, get: function () { return deployment_1.deployment; } });
8
- var manifest_1 = require("./manifest");
9
- Object.defineProperty(exports, "manifest", { enumerable: true, get: function () { return manifest_1.manifest; } });
1
+ export { Factory } from './Factory.js';
10
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAChB,2CAAyC;AAAhC,wGAAA,UAAU,OAAA;AACnB,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Measure } from 'openspan';
2
+ import type { Scope } from './Storage.ts';
3
+ export declare function operation(method: string, scope?: Scope): Measure;
@@ -0,0 +1,23 @@
1
+ import { registry } from 'openspan';
2
+ /**
3
+ * What a BLOB storage measures. Network I/O to a third party, and nothing else reports it.
4
+ *
5
+ * `storage` is the name the component declared it under and `provider` is what stands behind it:
6
+ * a component declares several and uses them for different things, so the provider alone does not
7
+ * say which one was slow where two declarations share one.
8
+ */
9
+ const meters = registry();
10
+ /** Wider than a query's, because a third party over the network is slower than a database. */
11
+ const DURATIONS = [0.01, 0.05, 0.1, 0.5, 1, 2.5, 5, 10, 30];
12
+ const duration = meters.histogram('toa.blob.operation.duration', { buckets: DURATIONS, unit: 's' }, { storage: null, provider: null, operation: null });
13
+ export function operation(method, scope) {
14
+ return {
15
+ histogram: duration,
16
+ labels: {
17
+ storage: scope?.name,
18
+ provider: scope?.provider,
19
+ operation: method
20
+ }
21
+ };
22
+ }
23
+ //# sourceMappingURL=measurements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measurements.js","sourceRoot":"","sources":["../source/measurements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAInC;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAA;AAEzB,8FAA8F;AAC9F,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;AAE3D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAC/B,6BAA6B,EAC7B,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EACjC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CACnD,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,KAAa;IACrD,OAAO;QACL,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,EAAE,IAAI;YACpB,QAAQ,EAAE,KAAK,EAAE,QAAQ;YACzB,SAAS,EAAE,MAAM;SAClB;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { Readable } from 'node:stream';
2
+ import { Provider } from '../Provider.ts';
3
+ import type { Maybe } from '@toa.io/core/types';
4
+ import type { Metadata, Stream } from '../Entry.ts';
5
+ import type { Secret, Secrets } from '../Secrets.ts';
6
+ import type { TransformationOptions } from 'cloudinary';
7
+ export type CloudinarySecrets = Secrets<'API_KEY' | 'API_SECRET'>;
8
+ export declare class Cloudinary extends Provider<CloudinaryOptions> {
9
+ static readonly SECRETS: readonly Secret[];
10
+ private readonly type;
11
+ private readonly eager;
12
+ private readonly transformations;
13
+ private readonly config;
14
+ private readonly prefix;
15
+ constructor(options: CloudinaryOptions, secrets?: CloudinarySecrets);
16
+ get(path: string, options?: GetOptions): Promise<Maybe<Stream>>;
17
+ head(path: string): Promise<Maybe<Metadata>>;
18
+ put(path: string, stream: Readable): Promise<void>;
19
+ commit(): Promise<void>;
20
+ delete(path: string): Promise<void>;
21
+ move(from: string, to: string): Promise<void | Error>;
22
+ private fetch;
23
+ /**
24
+ * Where Cloudinary delivers the file or a variant of it, by its extension as `get` reads one:
25
+ * an address of what may not be there, which costs no request to make.
26
+ */
27
+ url(path: string): Promise<Maybe<string>>;
28
+ private address;
29
+ private toTransformation;
30
+ private mapTransformation;
31
+ private metadata;
32
+ private cloudinary;
33
+ }
34
+ interface GetOptions {
35
+ agent?: string;
36
+ range?: string;
37
+ }
38
+ export interface CloudinaryOptions {
39
+ environment: string;
40
+ type: StorageType;
41
+ prefix?: string;
42
+ eager?: TransformationOptions[];
43
+ transformations?: TransformationDeclaration[];
44
+ }
45
+ type TransformationDeclaration = Omit<Transformation, 'extension'> & {
46
+ extension: string;
47
+ };
48
+ interface Transformation {
49
+ extension: RegExp;
50
+ condition?: string;
51
+ transformation: Record<string, unknown> | Array<Record<string, unknown>>;
52
+ optional?: boolean;
53
+ }
54
+ type StorageType = 'image' | 'video';
55
+ export {};
@@ -0,0 +1,232 @@
1
+ import { basename, dirname, join } from 'node:path';
2
+ import { Readable } from 'node:stream';
3
+ import { v2 as cloudinary } from 'cloudinary';
4
+ import { console } from 'openspan';
5
+ import { Provider } from '../Provider.js';
6
+ import { secrets } from '@toa.io/definitions/extensions.storages';
7
+ import { ERR_NOT_FOUND } from '../errors.js';
8
+ export class Cloudinary extends Provider {
9
+ static SECRETS = secrets.cloudinary;
10
+ type;
11
+ eager = [];
12
+ transformations = [];
13
+ config;
14
+ prefix;
15
+ constructor(options, secrets) {
16
+ super(options, secrets);
17
+ this.type = options.type;
18
+ if (options.eager !== undefined)
19
+ this.eager = options.eager;
20
+ if (options.transformations !== undefined)
21
+ this.transformations = options.transformations.map((transformation) => {
22
+ const { extension, ...rest } = transformation;
23
+ let expression = extension;
24
+ if (!extension.startsWith('^'))
25
+ expression = '^' + extension;
26
+ if (!extension.endsWith('$'))
27
+ expression = extension + '$';
28
+ return {
29
+ extension: new RegExp(expression),
30
+ ...rest
31
+ };
32
+ });
33
+ this.config = {
34
+ cloud_name: options.environment,
35
+ api_key: secrets.API_KEY,
36
+ api_secret: secrets.API_SECRET
37
+ };
38
+ this.prefix = options.prefix ?? '/';
39
+ }
40
+ async get(path, options) {
41
+ const headers = {};
42
+ if (options?.range !== undefined)
43
+ headers.range = options.range;
44
+ if (options?.agent !== undefined)
45
+ headers['user-agent'] = options.agent;
46
+ const response = await this.fetch(path, { method: 'GET', headers });
47
+ if (response instanceof Error)
48
+ return ERR_NOT_FOUND;
49
+ const metadata = this.metadata(response);
50
+ return {
51
+ stream: Readable.fromWeb(response.body),
52
+ ...metadata
53
+ };
54
+ }
55
+ async head(path) {
56
+ const response = await this.fetch(path, { method: 'HEAD' });
57
+ if (response instanceof Error)
58
+ return ERR_NOT_FOUND;
59
+ return this.metadata(response);
60
+ }
61
+ async put(path, stream) {
62
+ const id = basename(path);
63
+ const folder = join(this.prefix, dirname(path));
64
+ await new Promise((resolve, reject) => {
65
+ const options = {
66
+ public_id: id,
67
+ folder,
68
+ eager: this.eager,
69
+ resource_type: this.type
70
+ };
71
+ console.debug('Uploading to Cloudinary', { path, options });
72
+ stream.pipe(this.cloudinary().uploader.upload_stream(options, (error, result) => {
73
+ if (error !== undefined)
74
+ reject(error);
75
+ else
76
+ resolve(result);
77
+ }));
78
+ stream.on('error', (e) => {
79
+ console.error('Cloudinary stream error', { path, error: e });
80
+ stream.destroy();
81
+ reject(e);
82
+ });
83
+ });
84
+ }
85
+ async commit() {
86
+ // metadata is read-only
87
+ }
88
+ async delete(path) {
89
+ const id = join(this.prefix, path);
90
+ console.debug('Deleting from Cloudinary', { path: id });
91
+ await this.cloudinary().uploader.destroy(id, {
92
+ resource_type: this.type,
93
+ invalidate: true
94
+ });
95
+ }
96
+ async move(from, to) {
97
+ const source = join(this.prefix, from);
98
+ const target = join(this.prefix, to);
99
+ try {
100
+ await this.cloudinary().uploader.rename(source, target, {
101
+ resource_type: this.type,
102
+ overwrite: true
103
+ });
104
+ }
105
+ catch (error) {
106
+ if (error.http_code === 404)
107
+ return ERR_NOT_FOUND;
108
+ else
109
+ throw error;
110
+ }
111
+ }
112
+ async fetch(path, options = { method: 'GET' }) {
113
+ const url = this.address(path);
114
+ if (url === null)
115
+ return ERR_NOT_FOUND;
116
+ console.debug('Fetching from Cloudinary', {
117
+ method: options.method,
118
+ path,
119
+ url
120
+ });
121
+ const response = await fetch(url, options).catch((e) => e);
122
+ if (response instanceof Error || response.ok === false) {
123
+ console.debug('Failed to fetch from Cloudinary', {
124
+ url,
125
+ status: response.status,
126
+ message: response.message
127
+ });
128
+ return ERR_NOT_FOUND;
129
+ }
130
+ else
131
+ console.debug('Received response from Cloudinary', {
132
+ url,
133
+ status: response.status,
134
+ headers: response.headers
135
+ });
136
+ return response;
137
+ }
138
+ /**
139
+ * Where Cloudinary delivers the file or a variant of it, by its extension as `get` reads one:
140
+ * an address of what may not be there, which costs no request to make.
141
+ */
142
+ async url(path) {
143
+ return this.address(path, true) ?? ERR_NOT_FOUND;
144
+ }
145
+ address(path, secure = false) {
146
+ const [base, transformation] = this.toTransformation(path);
147
+ if (base === null)
148
+ return null;
149
+ const id = join(this.prefix, base);
150
+ return this.cloudinary().url(id, {
151
+ resource_type: this.type,
152
+ transformation,
153
+ version: 2,
154
+ secure,
155
+ urlAnalytics: false
156
+ });
157
+ }
158
+ toTransformation(path) {
159
+ if (this.transformations.length === 0)
160
+ return [path, undefined];
161
+ const [base, ...extensions] = path.split('.');
162
+ const transformations = [];
163
+ let t = 0;
164
+ for (const extension of extensions) {
165
+ let found = false;
166
+ for (t; t < this.transformations.length && !found; t++) {
167
+ const { extension: regex, condition, transformation, optional } = this.transformations[t];
168
+ const match = regex.exec(extension);
169
+ // eslint-disable-next-line max-depth
170
+ if (match === null)
171
+ if (optional === true)
172
+ continue;
173
+ else
174
+ return [null, undefined];
175
+ const options = Array.isArray(transformation) ? transformation : [transformation];
176
+ const stages = options.map((stage) => this.mapTransformation(stage, match.groups));
177
+ found = true;
178
+ if (condition === undefined)
179
+ transformations.push(...stages);
180
+ else {
181
+ transformations.push({ if: condition });
182
+ transformations.push(...stages);
183
+ transformations.push({ if: 'end' });
184
+ }
185
+ }
186
+ if (!found)
187
+ return [null, undefined];
188
+ }
189
+ for (t; t < this.transformations.length; t++)
190
+ if (this.transformations[t].optional !== true)
191
+ return [null, undefined];
192
+ return [base, transformations];
193
+ }
194
+ mapTransformation(options, groups) {
195
+ return Object.fromEntries(Object.entries(options).map(([key, value]) => {
196
+ if (typeof value !== 'string')
197
+ return [key, value];
198
+ if (value.startsWith('<') && value.endsWith('>'))
199
+ value = groups[value.slice(1, -1)];
200
+ if (key === 'zoom' && value !== undefined)
201
+ value = Number.parseInt(value) / 100;
202
+ if (key === 'fetch_format' && value === 'jpeg')
203
+ value = 'jpg';
204
+ return [key, value];
205
+ }));
206
+ }
207
+ metadata(response) {
208
+ const size = response.headers.get('content-length') === null
209
+ ? null
210
+ : Number.parseInt(response.headers.get('content-length'));
211
+ const created = response.headers.get('date') ?? new Date().toISOString();
212
+ const etag = response.headers.get('etag');
213
+ const checksum = etag === null ? basename(response.url) : etag.slice(1, -1);
214
+ const range = response.headers.get('content-range');
215
+ return {
216
+ type: response.headers.get('content-type'),
217
+ size,
218
+ checksum,
219
+ created,
220
+ range: range ?? undefined,
221
+ partial: response.status === 206,
222
+ attributes: {
223
+ url: response.url
224
+ }
225
+ };
226
+ }
227
+ cloudinary() {
228
+ cloudinary.config(this.config);
229
+ return cloudinary;
230
+ }
231
+ }
232
+ //# sourceMappingURL=Cloudinary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Cloudinary.js","sourceRoot":"","sources":["../../source/providers/Cloudinary.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,18 @@
1
- import type { S3Options } from './S3';
2
- import type { FileSystemOptions } from './FileSystem';
3
- import type { TemporaryOptions } from './Temporary';
1
+ import type { S3Options } from './S3.ts';
2
+ import type { SpacesOptions } from './Spaces.ts';
3
+ import type { CloudinaryOptions } from './Cloudinary.ts';
4
+ import type { FileSystemOptions } from './FileSystem.ts';
5
+ import type { TemporaryOptions } from './Temporary.ts';
4
6
  export type Declaration = ({
5
7
  provider: 's3';
6
8
  } & S3Options) | ({
9
+ provider: 'spaces';
10
+ } & SpacesOptions) | ({
11
+ provider: 'cloudinary';
12
+ } & CloudinaryOptions) | ({
7
13
  provider: 'fs';
8
14
  } & FileSystemOptions) | ({
9
15
  provider: 'tmp';
10
16
  } & TemporaryOptions) | ({
11
- provider: 'mem';
12
- }) | ({
13
17
  provider: 'test';
14
18
  } & TemporaryOptions);
@@ -1,3 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
3
2
  //# sourceMappingURL=Declaration.js.map
@@ -1,17 +1,22 @@
1
- /// <reference types="node" />
2
- import { type Readable } from 'node:stream';
3
- import { Provider } from '../Provider';
4
- import type { ProviderSecrets } from '../Provider';
1
+ import { Provider } from '../Provider.ts';
2
+ import type { Readable } from 'node:stream';
3
+ import type { Maybe } from '@toa.io/core/types';
4
+ import type { Metadata, Stream } from '../Entry.ts';
5
5
  export interface FileSystemOptions {
6
6
  path: string;
7
+ claim?: string;
7
8
  }
8
9
  export declare class FileSystem extends Provider<FileSystemOptions> {
9
- protected readonly path: string;
10
- constructor(options: FileSystemOptions, secrets?: ProviderSecrets);
11
- get(path: string): Promise<Readable | null>;
12
- list(path: string): Promise<string[]>;
13
- put(rel: string, filename: string, stream: Readable): Promise<void>;
10
+ readonly root: string;
11
+ constructor(options: FileSystemOptions);
12
+ get(rel: string): Promise<Maybe<Stream>>;
13
+ head(rel: string): Promise<Maybe<Metadata>>;
14
+ put(rel: string, stream: Readable): Promise<void>;
15
+ commit(rel: string, metadata: Metadata): Promise<void>;
14
16
  delete(path: string): Promise<void>;
15
- move(from: string, to: string): Promise<void>;
16
- moveDir(from: string, to: string): Promise<void>;
17
+ move(from: string, to: string): Promise<Maybe<void>>;
18
+ private blob;
19
+ private meta;
20
+ private join;
21
+ private try;
17
22
  }
@@ -1,53 +1,74 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.FileSystem = void 0;
7
- const node_path_1 = require("node:path");
8
- const promises_1 = __importDefault(require("node:fs/promises"));
9
- const Provider_1 = require("../Provider");
10
- class FileSystem extends Provider_1.Provider {
11
- path;
12
- constructor(options, secrets) {
13
- super(options, secrets);
14
- this.path = options.path;
15
- }
16
- async get(path) {
17
- try {
18
- const fd = await promises_1.default.open((0, node_path_1.join)(this.path, path));
19
- return fd.createReadStream();
20
- }
21
- catch (err) {
22
- if (err?.code === 'ENOENT')
23
- return null;
24
- throw err;
25
- }
1
+ import fs from 'node:fs/promises';
2
+ import { createReadStream } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { Provider } from '../Provider.js';
5
+ import { ERR_NOT_FOUND } from '../errors.js';
6
+ export class FileSystem extends Provider {
7
+ root;
8
+ constructor(options) {
9
+ super(options);
10
+ this.root = options.path;
11
+ }
12
+ async get(rel) {
13
+ const path = this.blob(rel);
14
+ const metadata = await this.head(rel);
15
+ if (metadata instanceof Error)
16
+ return metadata;
17
+ const stream = createReadStream(path);
18
+ return { stream, ...metadata };
26
19
  }
27
- async list(path) {
28
- const dir = (0, node_path_1.join)(this.path, path);
29
- return (await promises_1.default.readdir(dir, { withFileTypes: true }))
30
- .filter((dirent) => dirent.isFile())
31
- .map((dirent) => dirent.name);
20
+ async head(rel) {
21
+ const path = this.meta(rel);
22
+ return this.try(async () => {
23
+ const contents = await fs.readFile(path, 'utf8');
24
+ return JSON.parse(contents);
25
+ });
32
26
  }
33
- async put(rel, filename, stream) {
34
- const dir = (0, node_path_1.join)(this.path, rel);
35
- const path = (0, node_path_1.join)(dir, filename);
36
- await promises_1.default.mkdir(dir, { recursive: true });
37
- await promises_1.default.writeFile(path, stream);
27
+ async put(rel, stream) {
28
+ const path = this.blob(rel);
29
+ const dir = dirname(path);
30
+ await fs.mkdir(dir, { recursive: true });
31
+ await fs.writeFile(path, stream);
32
+ }
33
+ async commit(rel, metadata) {
34
+ const path = this.meta(rel);
35
+ await fs.writeFile(path, JSON.stringify(metadata), 'utf8');
38
36
  }
39
37
  async delete(path) {
40
- await promises_1.default.rm((0, node_path_1.join)(this.path, path), { recursive: true, force: true });
38
+ await Promise.all([
39
+ fs.rm(this.blob(path), { force: true }),
40
+ fs.rm(this.meta(path), { force: true })
41
+ ]);
41
42
  }
42
43
  async move(from, to) {
43
- from = (0, node_path_1.join)(this.path, from);
44
- to = (0, node_path_1.join)(this.path, to);
45
- await promises_1.default.mkdir((0, node_path_1.dirname)(to), { recursive: true });
46
- await promises_1.default.rename(from, to);
44
+ const bf = this.blob(from);
45
+ const bt = this.blob(to);
46
+ const mf = this.meta(from);
47
+ const mt = this.meta(to);
48
+ await fs.mkdir(dirname(bt), { recursive: true });
49
+ return await this.try(async () => {
50
+ await Promise.all([fs.rename(bf, bt), fs.rename(mf, mt)]);
51
+ });
52
+ }
53
+ blob(rel) {
54
+ return this.join(rel, '.blob');
47
55
  }
48
- async moveDir(from, to) {
49
- await this.move(from, to).catch(() => null);
56
+ meta(rel) {
57
+ return this.join(rel, '.meta');
58
+ }
59
+ join(rel, ext) {
60
+ return join(this.root, rel) + ext;
61
+ }
62
+ async try(action) {
63
+ try {
64
+ return await action();
65
+ }
66
+ catch (err) {
67
+ if (err?.code === 'ENOENT')
68
+ return ERR_NOT_FOUND;
69
+ else
70
+ throw err;
71
+ }
50
72
  }
51
73
  }
52
- exports.FileSystem = FileSystem;
53
74
  //# sourceMappingURL=FileSystem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileSystem.js","sourceRoot":"","sources":["../../source/providers/FileSystem.ts"],"names":[],"mappings":";;;;;;AACA,yCAAyC;AACzC,gEAAiC;AACjC,0CAAsC;AAOtC,MAAa,UAAW,SAAQ,mBAA2B;IACtC,IAAI,CAAQ;IAE/B,YAAoB,OAA0B,EAAE,OAAyB;QACvE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAEvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IAC1B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,IAAY;QAC5B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;YAE/C,OAAO,EAAE,CAAC,gBAAgB,EAAE,CAAA;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,EAAE,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAElE,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI,CAAE,IAAY;QAC7B,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAEjC,OAAO,CAAC,MAAM,kBAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;aACpD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;aACnC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,GAAW,EAAE,QAAgB,EAAE,MAAgB;QAC/D,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAEhC,MAAM,kBAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACxC,MAAM,kBAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAClC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,IAAY;QAC/B,MAAM,kBAAE,CAAC,EAAE,CAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtE,CAAC;IAEM,KAAK,CAAC,IAAI,CAAE,IAAY,EAAE,EAAU;QACzC,IAAI,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5B,EAAE,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAExB,MAAM,kBAAE,CAAC,KAAK,CAAC,IAAA,mBAAO,EAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAChD,MAAM,kBAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAC3B,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,IAAY,EAAE,EAAU;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC7C,CAAC;CACF;AApDD,gCAoDC"}
1
+ {"version":3,"file":"FileSystem.js","sourceRoot":"","sources":["../../source/providers/FileSystem.ts"],"names":[],"mappings":"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"}