@elaraai/e3-cloud-files 0.0.0-stage → 1.0.91-alpha.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.
- package/LICENSE.md +54 -0
- package/README.md +227 -2
- package/dist/src/authoring.d.ts +114 -0
- package/dist/src/authoring.d.ts.map +1 -0
- package/dist/src/authoring.js +178 -0
- package/dist/src/authoring.js.map +1 -0
- package/dist/src/check/index.d.ts +15 -0
- package/dist/src/check/index.d.ts.map +1 -0
- package/dist/src/check/index.js +15 -0
- package/dist/src/check/index.js.map +1 -0
- package/dist/src/check.d.ts +66 -0
- package/dist/src/check.d.ts.map +1 -0
- package/dist/src/check.js +140 -0
- package/dist/src/check.js.map +1 -0
- package/dist/src/index.d.ts +27 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +27 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/paths.d.ts +59 -0
- package/dist/src/paths.d.ts.map +1 -0
- package/dist/src/paths.js +114 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/s3/index.d.ts +37 -0
- package/dist/src/s3/index.d.ts.map +1 -0
- package/dist/src/s3/index.js +76 -0
- package/dist/src/s3/index.js.map +1 -0
- package/dist/src/storage/index.d.ts +16 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +117 -0
- package/dist/src/storage/index.js.map +1 -0
- package/dist/src/sync/engine.d.ts +136 -0
- package/dist/src/sync/engine.d.ts.map +1 -0
- package/dist/src/sync/engine.js +345 -0
- package/dist/src/sync/engine.js.map +1 -0
- package/dist/src/sync/index.d.ts +15 -0
- package/dist/src/sync/index.d.ts.map +1 -0
- package/dist/src/sync/index.js +15 -0
- package/dist/src/sync/index.js.map +1 -0
- package/dist/src/sync/memory.d.ts +65 -0
- package/dist/src/sync/memory.d.ts.map +1 -0
- package/dist/src/sync/memory.js +127 -0
- package/dist/src/sync/memory.js.map +1 -0
- package/dist/test/decode.examples.d.ts +33 -0
- package/dist/test/decode.examples.d.ts.map +1 -0
- package/dist/test/decode.examples.js +103 -0
- package/dist/test/decode.examples.js.map +1 -0
- package/dist/test/orders.examples.d.ts +88 -0
- package/dist/test/orders.examples.d.ts.map +1 -0
- package/dist/test/orders.examples.js +71 -0
- package/dist/test/orders.examples.js.map +1 -0
- package/package.json +76 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether declarations fit a package, and bindings fit declarations.
|
|
7
|
+
*
|
|
8
|
+
* {@link checkFiles} is the one check every deploy of declarations runs, on a
|
|
9
|
+
* local repository and in the cloud: each mapping's input exists, is an
|
|
10
|
+
* input, and is of its shape's type, compared exactly. {@link checkBindings}
|
|
11
|
+
* is what a bind runs. {@link readPackageInputs} reads a package's inputs
|
|
12
|
+
* from its objects, through a reader: the store's on a server, a local
|
|
13
|
+
* repository's on a machine.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { type EastTypeValue } from '@elaraai/east';
|
|
18
|
+
import { type FilesBinding, type FilesManifest, type FilesProblem, type FilesShape } from '@elaraai/e3-cloud-types';
|
|
19
|
+
/** An input of a package. */
|
|
20
|
+
export interface PackageInput {
|
|
21
|
+
/** Its type */
|
|
22
|
+
readonly type: EastTypeValue;
|
|
23
|
+
/** Whether anything may write it: inputs are writable; task outputs and records are not */
|
|
24
|
+
readonly writable: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Reads an object of a package's repository by hash. */
|
|
27
|
+
export type ObjectReader = (hash: string) => Promise<Uint8Array>;
|
|
28
|
+
/** The type a shape's input holds. */
|
|
29
|
+
export declare function shapeType(shape: FilesShape): EastTypeValue;
|
|
30
|
+
/**
|
|
31
|
+
* Reads a package's inputs, `.inputs.<name>`, from its objects.
|
|
32
|
+
*
|
|
33
|
+
* @param read - Reads an object by hash
|
|
34
|
+
* @param packageHash - The package object's hash
|
|
35
|
+
* @returns Each input, by name
|
|
36
|
+
*/
|
|
37
|
+
export declare function readPackageInputs(read: ObjectReader, packageHash: string): Promise<Map<string, PackageInput>>;
|
|
38
|
+
/**
|
|
39
|
+
* The problems of declarations against a package, none when they fit. Each
|
|
40
|
+
* mapping's input must be an input of the package, of its shape's type.
|
|
41
|
+
*
|
|
42
|
+
* @param manifest - The declarations
|
|
43
|
+
* @param inputs - The package's inputs ({@link readPackageInputs})
|
|
44
|
+
* @returns Every problem
|
|
45
|
+
*/
|
|
46
|
+
export declare function checkFiles(manifest: FilesManifest, inputs: ReadonlyMap<string, PackageInput>): FilesProblem[];
|
|
47
|
+
/** Where a binding may point: for a deployed workspace, the sources the deployment grants. */
|
|
48
|
+
export interface BindingPolicy {
|
|
49
|
+
/** Whether the bindings are a local repository's, where `profile` and `latest` apply */
|
|
50
|
+
readonly local: boolean;
|
|
51
|
+
/** The buckets and prefixes the deployment grants, for a deployed workspace; any URL locally */
|
|
52
|
+
readonly granted?: readonly {
|
|
53
|
+
readonly bucket: string;
|
|
54
|
+
readonly prefixes: readonly string[];
|
|
55
|
+
}[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The problems of bindings against declarations, none when they fit.
|
|
59
|
+
*
|
|
60
|
+
* @param manifest - The declarations
|
|
61
|
+
* @param bindings - The bindings
|
|
62
|
+
* @param policy - Where they may point
|
|
63
|
+
* @returns Every problem
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkBindings(manifest: FilesManifest, bindings: readonly FilesBinding[], policy: BindingPolicy): FilesProblem[];
|
|
66
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EAAoD,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAErG,OAAO,EAEL,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAC1E,MAAM,yBAAyB,CAAC;AAGjC,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,eAAe;IACf,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAIjE,sCAAsC;AACtC,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAU1D;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAWnH;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,YAAY,EAAE,CAgC7G;AAED,8FAA8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;CACjG;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,YAAY,EAAE,EAAE,MAAM,EAAE,aAAa,GAAG,YAAY,EAAE,CAuB/H"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether declarations fit a package, and bindings fit declarations.
|
|
7
|
+
*
|
|
8
|
+
* {@link checkFiles} is the one check every deploy of declarations runs, on a
|
|
9
|
+
* local repository and in the cloud: each mapping's input exists, is an
|
|
10
|
+
* input, and is of its shape's type, compared exactly. {@link checkBindings}
|
|
11
|
+
* is what a bind runs. {@link readPackageInputs} reads a package's inputs
|
|
12
|
+
* from its objects, through a reader: the store's on a server, a local
|
|
13
|
+
* repository's on a machine.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { EastTypeType, equalFor, toEastTypeValue, variant } from '@elaraai/east';
|
|
18
|
+
import { decodePackageObject } from '@elaraai/e3-types';
|
|
19
|
+
import { FilesFileType, FilesFolderType, FilesListingType, } from '@elaraai/e3-cloud-types';
|
|
20
|
+
import { includeProblem, keyProblem, parseBucketUrl, prefixProblem } from './paths.js';
|
|
21
|
+
const typesEqual = equalFor(EastTypeType);
|
|
22
|
+
/** The type a shape's input holds. */
|
|
23
|
+
export function shapeType(shape) {
|
|
24
|
+
switch (shape.type) {
|
|
25
|
+
case 'file':
|
|
26
|
+
case 'latest':
|
|
27
|
+
return toEastTypeValue(FilesFileType);
|
|
28
|
+
case 'folder':
|
|
29
|
+
return toEastTypeValue(FilesFolderType);
|
|
30
|
+
case 'listing':
|
|
31
|
+
return toEastTypeValue(FilesListingType);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Reads a package's inputs, `.inputs.<name>`, from its objects.
|
|
36
|
+
*
|
|
37
|
+
* @param read - Reads an object by hash
|
|
38
|
+
* @param packageHash - The package object's hash
|
|
39
|
+
* @returns Each input, by name
|
|
40
|
+
*/
|
|
41
|
+
export async function readPackageInputs(read, packageHash) {
|
|
42
|
+
const pkg = decodePackageObject(await read(packageHash));
|
|
43
|
+
const inputs = new Map();
|
|
44
|
+
const root = pkg.data.structure;
|
|
45
|
+
if (root.type !== 'struct')
|
|
46
|
+
return inputs;
|
|
47
|
+
const tree = root.value.get('inputs');
|
|
48
|
+
if (tree === undefined || tree.type !== 'struct')
|
|
49
|
+
return inputs;
|
|
50
|
+
for (const [name, child] of tree.value) {
|
|
51
|
+
if (child.type === 'value')
|
|
52
|
+
inputs.set(name, { type: child.value.type, writable: child.value.writable });
|
|
53
|
+
}
|
|
54
|
+
return inputs;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The problems of declarations against a package, none when they fit. Each
|
|
58
|
+
* mapping's input must be an input of the package, of its shape's type.
|
|
59
|
+
*
|
|
60
|
+
* @param manifest - The declarations
|
|
61
|
+
* @param inputs - The package's inputs ({@link readPackageInputs})
|
|
62
|
+
* @returns Every problem
|
|
63
|
+
*/
|
|
64
|
+
export function checkFiles(manifest, inputs) {
|
|
65
|
+
const problems = [];
|
|
66
|
+
const seen = new Set();
|
|
67
|
+
const sources = new Set(manifest.sources);
|
|
68
|
+
for (const mapping of manifest.mappings) {
|
|
69
|
+
const { input, shape } = mapping;
|
|
70
|
+
if (seen.has(input))
|
|
71
|
+
problems.push(variant('duplicate_input', { input }));
|
|
72
|
+
seen.add(input);
|
|
73
|
+
if (!sources.has(mapping.source))
|
|
74
|
+
problems.push(variant('source_unknown', { source: mapping.source }));
|
|
75
|
+
// What the declarations alone get wrong, as a declaration would have refused it
|
|
76
|
+
if (shape.type === 'file') {
|
|
77
|
+
const reason = keyProblem(shape.value.key);
|
|
78
|
+
if (reason !== null)
|
|
79
|
+
problems.push(variant('invalid_key', { input, key: shape.value.key, reason }));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const reason = prefixProblem(shape.value.prefix);
|
|
83
|
+
if (reason !== null)
|
|
84
|
+
problems.push(variant('invalid_key', { input, key: shape.value.prefix, reason }));
|
|
85
|
+
if (shape.value.include.type === 'some') {
|
|
86
|
+
const include = includeProblem(shape.value.include.value);
|
|
87
|
+
if (include !== null)
|
|
88
|
+
problems.push(variant('invalid_include', { input, include: shape.value.include.value, reason: include }));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const expected = shapeType(shape);
|
|
92
|
+
const declared = inputs.get(input);
|
|
93
|
+
if (declared === undefined) {
|
|
94
|
+
problems.push(variant('input_missing', { input, expected }));
|
|
95
|
+
}
|
|
96
|
+
else if (!declared.writable) {
|
|
97
|
+
problems.push(variant('input_not_writable', { input }));
|
|
98
|
+
}
|
|
99
|
+
else if (!typesEqual(declared.type, expected)) {
|
|
100
|
+
problems.push(variant('input_type', { input, expected, actual: declared.type }));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return problems;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The problems of bindings against declarations, none when they fit.
|
|
107
|
+
*
|
|
108
|
+
* @param manifest - The declarations
|
|
109
|
+
* @param bindings - The bindings
|
|
110
|
+
* @param policy - Where they may point
|
|
111
|
+
* @returns Every problem
|
|
112
|
+
*/
|
|
113
|
+
export function checkBindings(manifest, bindings, policy) {
|
|
114
|
+
const problems = [];
|
|
115
|
+
const sources = new Set(manifest.sources);
|
|
116
|
+
for (const binding of bindings) {
|
|
117
|
+
const { source, url } = binding;
|
|
118
|
+
if (!sources.has(source))
|
|
119
|
+
problems.push(variant('source_unknown', { source }));
|
|
120
|
+
const location = parseBucketUrl(url);
|
|
121
|
+
if ('problem' in location) {
|
|
122
|
+
problems.push(variant('invalid_url', { source, url, reason: location.problem }));
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (!policy.local) {
|
|
126
|
+
if (binding.profile.type === 'some')
|
|
127
|
+
problems.push(variant('local_only', { source, option: 'profile' }));
|
|
128
|
+
if (binding.latest.type === 'some')
|
|
129
|
+
problems.push(variant('local_only', { source, option: 'latest' }));
|
|
130
|
+
const granted = (policy.granted ?? []).some((grant) => grant.bucket === location.bucket && grant.prefixes.some((prefix) => location.prefix.startsWith(prefix)));
|
|
131
|
+
if (!granted)
|
|
132
|
+
problems.push(variant('not_granted', { source, url }));
|
|
133
|
+
}
|
|
134
|
+
if (binding.latest.type === 'some' && binding.latest.value < 1n) {
|
|
135
|
+
problems.push(variant('invalid_url', { source, url, reason: 'keeps fewer than one file (latest)' }));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return problems;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `@elaraai/e3-cloud-files`: a solution's inputs that come from files in a
|
|
7
|
+
* bucket.
|
|
8
|
+
*
|
|
9
|
+
* - `Files.source(name)`: a source, which each workspace binds to a bucket
|
|
10
|
+
* and a prefix; its `file`, `latest`, `folder` and `listing` declare the
|
|
11
|
+
* inputs its files fill, each an ordinary `e3.input`.
|
|
12
|
+
* - `Files.manifest(sources)`: the declarations `e3-cloud files deploy`
|
|
13
|
+
* deploys beside the package.
|
|
14
|
+
* - `checkFiles`, `checkBindings`, `readPackageInputs`: the checks a deploy
|
|
15
|
+
* and a bind run.
|
|
16
|
+
*
|
|
17
|
+
* A file arrives as it is, a `Blob`; the solution decodes it in East. The
|
|
18
|
+
* sync is `@elaraai/e3-cloud-files/sync`; the East types are
|
|
19
|
+
* `@elaraai/e3-cloud-types`'s `Files*`.
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
23
|
+
export { Files, FilesSource, FilesDeclarationError, type FilesInput, type FilesSelection } from './authoring.js';
|
|
24
|
+
export { checkFiles, checkBindings, readPackageInputs, shapeType, type PackageInput, type ObjectReader, type BindingPolicy, } from './check.js';
|
|
25
|
+
export { globMatcher, parseBucketUrl, keyProblem, prefixProblem, includeProblem, type BucketLocation } from './paths.js';
|
|
26
|
+
export { FilesManifestType, FilesMappingType, FilesShapeType, FilesBindingType, FilesSyncReportType, FilesMappingReportType, FilesStatusType, FilesProblemType, FilesListingRowType, FilesFileType, FilesFolderType, FilesListingType, FILES_FILE_MAX_BYTES, FILES_FOLDER_ENTRY_MAX_BYTES, filesProblemText, type FilesManifest, type FilesMapping, type FilesShape, type FilesBinding, type FilesSyncReport, type FilesMappingReport, type FilesStatus, type FilesProblem, type FilesListingRow, } from '@elaraai/e3-cloud-types';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjH,OAAO,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACzH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,4BAA4B,EAC5B,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `@elaraai/e3-cloud-files`: a solution's inputs that come from files in a
|
|
7
|
+
* bucket.
|
|
8
|
+
*
|
|
9
|
+
* - `Files.source(name)`: a source, which each workspace binds to a bucket
|
|
10
|
+
* and a prefix; its `file`, `latest`, `folder` and `listing` declare the
|
|
11
|
+
* inputs its files fill, each an ordinary `e3.input`.
|
|
12
|
+
* - `Files.manifest(sources)`: the declarations `e3-cloud files deploy`
|
|
13
|
+
* deploys beside the package.
|
|
14
|
+
* - `checkFiles`, `checkBindings`, `readPackageInputs`: the checks a deploy
|
|
15
|
+
* and a bind run.
|
|
16
|
+
*
|
|
17
|
+
* A file arrives as it is, a `Blob`; the solution decodes it in East. The
|
|
18
|
+
* sync is `@elaraai/e3-cloud-files/sync`; the East types are
|
|
19
|
+
* `@elaraai/e3-cloud-types`'s `Files*`.
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
23
|
+
export { Files, FilesSource, FilesDeclarationError } from './authoring.js';
|
|
24
|
+
export { checkFiles, checkBindings, readPackageInputs, shapeType, } from './check.js';
|
|
25
|
+
export { globMatcher, parseBucketUrl, keyProblem, prefixProblem, includeProblem } from './paths.js';
|
|
26
|
+
export { FilesManifestType, FilesMappingType, FilesShapeType, FilesBindingType, FilesSyncReportType, FilesMappingReportType, FilesStatusType, FilesProblemType, FilesListingRowType, FilesFileType, FilesFolderType, FilesListingType, FILES_FILE_MAX_BYTES, FILES_FOLDER_ENTRY_MAX_BYTES, filesProblemText, } from '@elaraai/e3-cloud-types';
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAwC,MAAM,gBAAgB,CAAC;AACjH,OAAO,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,SAAS,GAIV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AACzH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,4BAA4B,EAC5B,gBAAgB,GAUjB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The keys, prefixes and globs a mapping names, and the URLs a binding
|
|
7
|
+
* names: what makes each well-formed, and how a glob matches.
|
|
8
|
+
*
|
|
9
|
+
* A mapping's key or prefix is relative to where a workspace binds its
|
|
10
|
+
* source, so it never names a bucket and never begins with `/`. A prefix is
|
|
11
|
+
* a folder: empty for everything the binding holds, else ending with `/`.
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Why a key cannot name one file, or `null` when it can.
|
|
17
|
+
*
|
|
18
|
+
* @param key - The key, relative to the binding
|
|
19
|
+
* @returns The reason, completing "'<key>' …"
|
|
20
|
+
*/
|
|
21
|
+
export declare function keyProblem(key: string): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Why a prefix cannot name a folder, or `null` when it can.
|
|
24
|
+
*
|
|
25
|
+
* @param prefix - The prefix, relative to the binding: `''`, or ending with `/`
|
|
26
|
+
* @returns The reason, completing "'<prefix>' …"
|
|
27
|
+
*/
|
|
28
|
+
export declare function prefixProblem(prefix: string): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Why a glob cannot select files, or `null` when it can.
|
|
31
|
+
*
|
|
32
|
+
* @param include - The glob, over paths relative to the prefix
|
|
33
|
+
* @returns The reason, completing "include '<include>' …"
|
|
34
|
+
*/
|
|
35
|
+
export declare function includeProblem(include: string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* A glob's matcher over paths relative to a prefix: `*` matches within one
|
|
38
|
+
* segment of the path, `**` across segments, `?` one character but `/`, and
|
|
39
|
+
* every other character itself. No glob matches every path.
|
|
40
|
+
*
|
|
41
|
+
* @param include - The glob, or `null` for every path
|
|
42
|
+
* @returns Whether a path matches
|
|
43
|
+
*/
|
|
44
|
+
export declare function globMatcher(include: string | null): (path: string) => boolean;
|
|
45
|
+
/** A binding's URL, read: its bucket, and the prefix under it, `''` or ending with `/`. */
|
|
46
|
+
export interface BucketLocation {
|
|
47
|
+
readonly bucket: string;
|
|
48
|
+
readonly prefix: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reads a binding's URL, `s3://bucket/prefix/`.
|
|
52
|
+
*
|
|
53
|
+
* @param url - The URL
|
|
54
|
+
* @returns The bucket and the prefix, or the reason it is not one, completing "'<url>' …"
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseBucketUrl(url: string): BucketLocation | {
|
|
57
|
+
readonly problem: string;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK7D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAwB7E;AAED,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQzF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The keys, prefixes and globs a mapping names, and the URLs a binding
|
|
7
|
+
* names: what makes each well-formed, and how a glob matches.
|
|
8
|
+
*
|
|
9
|
+
* A mapping's key or prefix is relative to where a workspace binds its
|
|
10
|
+
* source, so it never names a bucket and never begins with `/`. A prefix is
|
|
11
|
+
* a folder: empty for everything the binding holds, else ending with `/`.
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Why a key cannot name one file, or `null` when it can.
|
|
17
|
+
*
|
|
18
|
+
* @param key - The key, relative to the binding
|
|
19
|
+
* @returns The reason, completing "'<key>' …"
|
|
20
|
+
*/
|
|
21
|
+
export function keyProblem(key) {
|
|
22
|
+
if (key === '')
|
|
23
|
+
return 'is empty';
|
|
24
|
+
if (key.startsWith('/'))
|
|
25
|
+
return 'begins with /: a key is relative to where the workspace binds its source';
|
|
26
|
+
if (key.endsWith('/'))
|
|
27
|
+
return 'ends with /, which names a folder rather than a file';
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Why a prefix cannot name a folder, or `null` when it can.
|
|
32
|
+
*
|
|
33
|
+
* @param prefix - The prefix, relative to the binding: `''`, or ending with `/`
|
|
34
|
+
* @returns The reason, completing "'<prefix>' …"
|
|
35
|
+
*/
|
|
36
|
+
export function prefixProblem(prefix) {
|
|
37
|
+
if (prefix.startsWith('/'))
|
|
38
|
+
return 'begins with /: a prefix is relative to where the workspace binds its source';
|
|
39
|
+
if (prefix !== '' && !prefix.endsWith('/'))
|
|
40
|
+
return "doesn't end with /: a prefix names a folder";
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Why a glob cannot select files, or `null` when it can.
|
|
45
|
+
*
|
|
46
|
+
* @param include - The glob, over paths relative to the prefix
|
|
47
|
+
* @returns The reason, completing "include '<include>' …"
|
|
48
|
+
*/
|
|
49
|
+
export function includeProblem(include) {
|
|
50
|
+
if (include === '')
|
|
51
|
+
return 'is empty';
|
|
52
|
+
if (include.startsWith('/'))
|
|
53
|
+
return 'begins with /: it matches paths relative to the prefix';
|
|
54
|
+
if (/\*{3,}/.test(include))
|
|
55
|
+
return 'has three or more * in a row';
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A glob's matcher over paths relative to a prefix: `*` matches within one
|
|
60
|
+
* segment of the path, `**` across segments, `?` one character but `/`, and
|
|
61
|
+
* every other character itself. No glob matches every path.
|
|
62
|
+
*
|
|
63
|
+
* @param include - The glob, or `null` for every path
|
|
64
|
+
* @returns Whether a path matches
|
|
65
|
+
*/
|
|
66
|
+
export function globMatcher(include) {
|
|
67
|
+
if (include === null)
|
|
68
|
+
return () => true;
|
|
69
|
+
let pattern = '';
|
|
70
|
+
for (let i = 0; i < include.length; i++) {
|
|
71
|
+
const c = include[i];
|
|
72
|
+
if (c === '*' && include[i + 1] === '*') {
|
|
73
|
+
// `**/` matches zero or more whole segments; a bare `**`, anything
|
|
74
|
+
if (include[i + 2] === '/') {
|
|
75
|
+
pattern += '(?:.*/)?';
|
|
76
|
+
i += 2;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
pattern += '.*';
|
|
80
|
+
i += 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (c === '*') {
|
|
84
|
+
pattern += '[^/]*';
|
|
85
|
+
}
|
|
86
|
+
else if (c === '?') {
|
|
87
|
+
pattern += '[^/]';
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
pattern += c.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const regex = new RegExp(`^${pattern}$`, 'su');
|
|
94
|
+
return (path) => regex.test(path);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reads a binding's URL, `s3://bucket/prefix/`.
|
|
98
|
+
*
|
|
99
|
+
* @param url - The URL
|
|
100
|
+
* @returns The bucket and the prefix, or the reason it is not one, completing "'<url>' …"
|
|
101
|
+
*/
|
|
102
|
+
export function parseBucketUrl(url) {
|
|
103
|
+
const match = /^s3:\/\/([^/]+)(?:\/(.*))?$/su.exec(url);
|
|
104
|
+
if (match === null)
|
|
105
|
+
return { problem: 'is not an s3://bucket/prefix/ URL' };
|
|
106
|
+
const bucket = match[1];
|
|
107
|
+
if (!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/u.test(bucket))
|
|
108
|
+
return { problem: `names '${bucket}', which isn't a bucket's name` };
|
|
109
|
+
const prefix = match[2] ?? '';
|
|
110
|
+
if (prefix !== '' && !prefix.endsWith('/'))
|
|
111
|
+
return { problem: "doesn't end with /: a binding names a folder" };
|
|
112
|
+
return { bucket, prefix };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `@elaraai/e3-cloud-files/s3`: the sync's reader of a bucket (`s3://`), one
|
|
7
|
+
* bound source read through a client the caller makes. The CLI makes it with
|
|
8
|
+
* the developer's own profile, the platform with a session scoped to the
|
|
9
|
+
* binding's bucket and prefix; both read through this.
|
|
10
|
+
*
|
|
11
|
+
* A listing is the bucket's, a page of 1,000 keys at a time, in key order. An
|
|
12
|
+
* ETag is kept without the quotes the bucket wraps it in. A file is read
|
|
13
|
+
* whole: at most 1 GiB for a `file` or `latest` input, 64 MiB for a folder's
|
|
14
|
+
* file.
|
|
15
|
+
*
|
|
16
|
+
* Needs `@aws-sdk/client-s3`, which a solution's own code never imports: the
|
|
17
|
+
* CLI and the platform do.
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
import { type S3Client } from '@aws-sdk/client-s3';
|
|
22
|
+
import type { FilesReader } from '../sync/engine.js';
|
|
23
|
+
/** Where a binding's files are: a bucket, and the prefix every key is relative to. */
|
|
24
|
+
export interface S3Location {
|
|
25
|
+
readonly bucket: string;
|
|
26
|
+
/** `''`, or ending with `/` */
|
|
27
|
+
readonly prefix: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The reader of one bound source in its bucket.
|
|
31
|
+
*
|
|
32
|
+
* @param client - The client to read with: its credentials and region are the caller's
|
|
33
|
+
* @param location - The bucket, and the prefix the binding names
|
|
34
|
+
* @returns The reader: its keys relative to the prefix
|
|
35
|
+
*/
|
|
36
|
+
export declare function s3FilesReader(client: S3Client, location: S3Location): FilesReader;
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/s3/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAiF,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClI,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAYD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,WAAW,CAkCjF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* `@elaraai/e3-cloud-files/s3`: the sync's reader of a bucket (`s3://`), one
|
|
7
|
+
* bound source read through a client the caller makes. The CLI makes it with
|
|
8
|
+
* the developer's own profile, the platform with a session scoped to the
|
|
9
|
+
* binding's bucket and prefix; both read through this.
|
|
10
|
+
*
|
|
11
|
+
* A listing is the bucket's, a page of 1,000 keys at a time, in key order. An
|
|
12
|
+
* ETag is kept without the quotes the bucket wraps it in. A file is read
|
|
13
|
+
* whole: at most 1 GiB for a `file` or `latest` input, 64 MiB for a folder's
|
|
14
|
+
* file.
|
|
15
|
+
*
|
|
16
|
+
* Needs `@aws-sdk/client-s3`, which a solution's own code never imports: the
|
|
17
|
+
* CLI and the platform do.
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
import { GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, S3ServiceException } from '@aws-sdk/client-s3';
|
|
22
|
+
/** An ETag without the quotes the bucket wraps it in. */
|
|
23
|
+
function bare(etag) {
|
|
24
|
+
return (etag ?? '').replace(/^"|"$/g, '');
|
|
25
|
+
}
|
|
26
|
+
/** Whether the bucket answered that there is no such key. */
|
|
27
|
+
function missing(err) {
|
|
28
|
+
return err instanceof S3ServiceException && (err.name === 'NotFound' || err.name === 'NoSuchKey' || err.$metadata.httpStatusCode === 404);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The reader of one bound source in its bucket.
|
|
32
|
+
*
|
|
33
|
+
* @param client - The client to read with: its credentials and region are the caller's
|
|
34
|
+
* @param location - The bucket, and the prefix the binding names
|
|
35
|
+
* @returns The reader: its keys relative to the prefix
|
|
36
|
+
*/
|
|
37
|
+
export function s3FilesReader(client, location) {
|
|
38
|
+
const absolute = (key) => `${location.prefix}${key}`;
|
|
39
|
+
return {
|
|
40
|
+
async *list(prefix) {
|
|
41
|
+
let token;
|
|
42
|
+
do {
|
|
43
|
+
const page = await client.send(new ListObjectsV2Command({ Bucket: location.bucket, Prefix: absolute(prefix), ContinuationToken: token }));
|
|
44
|
+
for (const object of page.Contents ?? []) {
|
|
45
|
+
if (object.Key === undefined)
|
|
46
|
+
continue;
|
|
47
|
+
yield {
|
|
48
|
+
key: object.Key.slice(location.prefix.length),
|
|
49
|
+
size: object.Size ?? 0,
|
|
50
|
+
modified: object.LastModified ?? new Date(0),
|
|
51
|
+
etag: bare(object.ETag),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
token = page.IsTruncated === true ? page.NextContinuationToken : undefined;
|
|
55
|
+
} while (token !== undefined);
|
|
56
|
+
},
|
|
57
|
+
async stat(key) {
|
|
58
|
+
try {
|
|
59
|
+
const head = await client.send(new HeadObjectCommand({ Bucket: location.bucket, Key: absolute(key) }));
|
|
60
|
+
return { key, size: head.ContentLength ?? 0, modified: head.LastModified ?? new Date(0), etag: bare(head.ETag) };
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (missing(err))
|
|
64
|
+
return null;
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
async read(key) {
|
|
69
|
+
const object = await client.send(new GetObjectCommand({ Bucket: location.bucket, Key: absolute(key) }));
|
|
70
|
+
if (object.Body === undefined)
|
|
71
|
+
throw new Error(`s3://${location.bucket}/${absolute(key)} answered no bytes`);
|
|
72
|
+
return object.Body.transformToByteArray();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/s3/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { type StorageBackend } from '@elaraai/e3-core';
|
|
6
|
+
import type { FilesWriter } from '../sync/engine.js';
|
|
7
|
+
/**
|
|
8
|
+
* The sync's writer over an e3 store, for one workspace.
|
|
9
|
+
*
|
|
10
|
+
* @param storage - The store: a local repository's (`LocalStorage`) or the platform's
|
|
11
|
+
* @param repo - The repository: a local repository's path, or the platform's repository name
|
|
12
|
+
* @param ws - The workspace
|
|
13
|
+
* @returns The writer
|
|
14
|
+
*/
|
|
15
|
+
export declare function storageWriter(storage: StorageBackend, repo: string, ws: string): FilesWriter;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAgDpE;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,CA+B5F"}
|