@elaraai/e3-cloud-cli 1.0.90 → 1.0.92
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/README.md +37 -0
- package/dist/src/app-source.d.ts +11 -0
- package/dist/src/app-source.d.ts.map +1 -1
- package/dist/src/app-source.js +8 -96
- package/dist/src/app-source.js.map +1 -1
- package/dist/src/cli.js +43 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/files.d.ts +47 -0
- package/dist/src/commands/files.d.ts.map +1 -0
- package/dist/src/commands/files.js +339 -0
- package/dist/src/commands/files.js.map +1 -0
- package/dist/src/commands/release.d.ts +3 -1
- package/dist/src/commands/release.d.ts.map +1 -1
- package/dist/src/commands/release.js +46 -3
- package/dist/src/commands/release.js.map +1 -1
- package/dist/src/files-local.d.ts +176 -0
- package/dist/src/files-local.d.ts.map +1 -0
- package/dist/src/files-local.js +258 -0
- package/dist/src/files-local.js.map +1 -0
- package/dist/src/files-source.d.ts +15 -0
- package/dist/src/files-source.d.ts.map +1 -0
- package/dist/src/files-source.js +41 -0
- package/dist/src/files-source.js.map +1 -0
- package/dist/src/source-module.d.ts +34 -0
- package/dist/src/source-module.d.ts.map +1 -0
- package/dist/src/source-module.js +108 -0
- package/dist/src/source-module.js.map +1 -0
- package/package.json +11 -8
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { ArrayType, DictType, OptionType, StringType, StructType, type ValueTypeOf } from '@elaraai/east';
|
|
6
|
+
import { type FilesBinding, type FilesManifest, type FilesProblem, type FilesStatus, type FilesSyncReport } from '@elaraai/e3-cloud-types';
|
|
7
|
+
import { type FilesLedger, type FilesReader } from '@elaraai/e3-cloud-files/sync';
|
|
8
|
+
/** What a local repository keeps of one workspace's Files. */
|
|
9
|
+
export declare const LocalFilesStateType: StructType<{
|
|
10
|
+
/** The declarations deployed to the workspace */
|
|
11
|
+
readonly manifest: OptionType<StructType<{
|
|
12
|
+
readonly sources: ArrayType<StringType>;
|
|
13
|
+
readonly mappings: ArrayType<StructType<{
|
|
14
|
+
readonly input: StringType;
|
|
15
|
+
readonly source: StringType;
|
|
16
|
+
readonly shape: import("@elaraai/east").VariantType<{
|
|
17
|
+
readonly file: StructType<{
|
|
18
|
+
readonly key: StringType;
|
|
19
|
+
}>;
|
|
20
|
+
readonly latest: StructType<{
|
|
21
|
+
readonly prefix: StringType;
|
|
22
|
+
readonly include: OptionType<StringType>;
|
|
23
|
+
}>;
|
|
24
|
+
readonly folder: StructType<{
|
|
25
|
+
readonly prefix: StringType;
|
|
26
|
+
readonly include: OptionType<StringType>;
|
|
27
|
+
}>;
|
|
28
|
+
readonly listing: StructType<{
|
|
29
|
+
readonly prefix: StringType;
|
|
30
|
+
readonly include: OptionType<StringType>;
|
|
31
|
+
}>;
|
|
32
|
+
}>;
|
|
33
|
+
}>>;
|
|
34
|
+
}>>;
|
|
35
|
+
/** Where each source is bound */
|
|
36
|
+
readonly bindings: ArrayType<StructType<{
|
|
37
|
+
readonly source: StringType;
|
|
38
|
+
readonly url: StringType;
|
|
39
|
+
readonly region: OptionType<StringType>;
|
|
40
|
+
readonly profile: OptionType<StringType>;
|
|
41
|
+
readonly latest: OptionType<import("@elaraai/east").IntegerType>;
|
|
42
|
+
}>>;
|
|
43
|
+
/** What each input took last, by input */
|
|
44
|
+
readonly ledgers: DictType<StringType, StructType<{
|
|
45
|
+
readonly entries: DictType<StringType, StructType<{
|
|
46
|
+
readonly etag: StringType;
|
|
47
|
+
readonly size: import("@elaraai/east").IntegerType;
|
|
48
|
+
}>>;
|
|
49
|
+
readonly value: OptionType<StringType>;
|
|
50
|
+
readonly under: OptionType<StringType>;
|
|
51
|
+
}>>;
|
|
52
|
+
/** The last sync's report; a dry run's is never kept */
|
|
53
|
+
readonly lastSync: OptionType<StructType<{
|
|
54
|
+
readonly started: import("@elaraai/east").DateTimeType;
|
|
55
|
+
readonly finished: import("@elaraai/east").DateTimeType;
|
|
56
|
+
readonly dryRun: import("@elaraai/east").BooleanType;
|
|
57
|
+
readonly mappings: ArrayType<StructType<{
|
|
58
|
+
readonly input: StringType;
|
|
59
|
+
readonly added: import("@elaraai/east").IntegerType;
|
|
60
|
+
readonly changed: import("@elaraai/east").IntegerType;
|
|
61
|
+
readonly removed: import("@elaraai/east").IntegerType;
|
|
62
|
+
readonly unchanged: import("@elaraai/east").IntegerType;
|
|
63
|
+
readonly refused: ArrayType<StructType<{
|
|
64
|
+
readonly key: StringType;
|
|
65
|
+
readonly reason: StringType;
|
|
66
|
+
}>>;
|
|
67
|
+
readonly bytes: import("@elaraai/east").IntegerType;
|
|
68
|
+
readonly updated: import("@elaraai/east").BooleanType;
|
|
69
|
+
}>>;
|
|
70
|
+
}>>;
|
|
71
|
+
}>;
|
|
72
|
+
export type LocalFilesState = ValueTypeOf<typeof LocalFilesStateType>;
|
|
73
|
+
/**
|
|
74
|
+
* Opens a local repository, as e3's CLI does: refused when this e3 cannot
|
|
75
|
+
* read it, upgraded in place when an older release wrote it.
|
|
76
|
+
*
|
|
77
|
+
* @param repoArg - The repository's path
|
|
78
|
+
* @returns Its absolute path
|
|
79
|
+
* @throws {Error} When there is no repository there, or this e3 cannot open it
|
|
80
|
+
*/
|
|
81
|
+
export declare function openLocalRepository(repoArg: string): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Where a repository keeps a workspace's Files.
|
|
84
|
+
*
|
|
85
|
+
* @throws {Error} When the name is no workspace's
|
|
86
|
+
*/
|
|
87
|
+
export declare function statePath(repoPath: string, ws: string): string;
|
|
88
|
+
/** What a repository keeps of a workspace's Files: nothing yet, before its first deploy. */
|
|
89
|
+
export declare function readState(repoPath: string, ws: string): LocalFilesState;
|
|
90
|
+
/** Keeps a workspace's Files, replacing the file whole so a reader never sees half of it. */
|
|
91
|
+
export declare function writeState(repoPath: string, ws: string, state: LocalFilesState): void;
|
|
92
|
+
/** The ledger over the repository's file: each write keeps what an input took the moment it is written. */
|
|
93
|
+
export declare function stateLedger(repoPath: string, ws: string): FilesLedger;
|
|
94
|
+
/**
|
|
95
|
+
* Reads each bound source's bucket with the developer's credentials: the
|
|
96
|
+
* binding's profile, else the SDK's usual chain (`AWS_PROFILE`, the
|
|
97
|
+
* environment, SSO). A bucket in another region than the one configured is
|
|
98
|
+
* followed there. A failure names the binding.
|
|
99
|
+
*
|
|
100
|
+
* @returns A reader for each binding, one client per profile and region
|
|
101
|
+
*/
|
|
102
|
+
export declare function s3Readers(): (binding: FilesBinding) => FilesReader;
|
|
103
|
+
/** What a deploy of declarations did, or would do. */
|
|
104
|
+
export interface LocalDeployResult {
|
|
105
|
+
/** The package the workspace runs, which the declarations were checked against */
|
|
106
|
+
readonly package: {
|
|
107
|
+
readonly name: string;
|
|
108
|
+
readonly version: string;
|
|
109
|
+
};
|
|
110
|
+
/** Why the declarations do not fit it; none when they were deployed */
|
|
111
|
+
readonly problems: readonly FilesProblem[];
|
|
112
|
+
/** The inputs whose declaration changed, which the next sync takes again whole */
|
|
113
|
+
readonly retaken: readonly string[];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Deploys declarations to a workspace, checked against the package it runs.
|
|
117
|
+
* An input whose declaration changed is taken again whole by the next sync.
|
|
118
|
+
*
|
|
119
|
+
* @param repoPath - The repository ({@link openLocalRepository})
|
|
120
|
+
* @param ws - The workspace
|
|
121
|
+
* @param manifest - The declarations
|
|
122
|
+
* @param options - `dryRun`: check them, and keep nothing
|
|
123
|
+
* @returns The package, every problem, and the inputs taken again
|
|
124
|
+
*/
|
|
125
|
+
export declare function deployLocal(repoPath: string, ws: string, manifest: FilesManifest, options?: {
|
|
126
|
+
dryRun?: boolean;
|
|
127
|
+
}): Promise<LocalDeployResult>;
|
|
128
|
+
/** What a bind did. */
|
|
129
|
+
export interface LocalBindResult {
|
|
130
|
+
/** Why the binding does not fit the declarations; none when it was kept */
|
|
131
|
+
readonly problems: readonly FilesProblem[];
|
|
132
|
+
/** The inputs the source fills, which the next sync takes again whole when the binding moved */
|
|
133
|
+
readonly retaken: readonly string[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Binds a source to where its files are, for a workspace. A binding moved to
|
|
137
|
+
* another URL has its inputs taken again whole by the next sync.
|
|
138
|
+
*
|
|
139
|
+
* @param repoPath - The repository
|
|
140
|
+
* @param ws - The workspace
|
|
141
|
+
* @param binding - The binding
|
|
142
|
+
* @returns Every problem, and the inputs taken again
|
|
143
|
+
* @throws {Error} When the workspace has no declarations deployed
|
|
144
|
+
*/
|
|
145
|
+
export declare function bindLocal(repoPath: string, ws: string, binding: FilesBinding): LocalBindResult;
|
|
146
|
+
/** What a local sync is given. */
|
|
147
|
+
export interface LocalSyncOptions {
|
|
148
|
+
/** Only these inputs; every declared input when absent */
|
|
149
|
+
readonly inputs?: readonly string[];
|
|
150
|
+
/** List what a sync would take, and take nothing */
|
|
151
|
+
readonly dryRun?: boolean;
|
|
152
|
+
/** Reads a bound source: its bucket, with the developer's credentials, when absent ({@link s3Readers}) */
|
|
153
|
+
readonly reader?: (binding: FilesBinding) => FilesReader;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Syncs a workspace's inputs with their sources' files. The declarations are
|
|
157
|
+
* checked again first, against the package the workspace runs now.
|
|
158
|
+
*
|
|
159
|
+
* @param repoPath - The repository
|
|
160
|
+
* @param ws - The workspace
|
|
161
|
+
* @param options - Which inputs, whether a dry run, and the reader
|
|
162
|
+
* @returns What it did, per input
|
|
163
|
+
* @throws {FilesSyncError} When the declarations no longer fit the package, or
|
|
164
|
+
* a source is not bound, before anything is read
|
|
165
|
+
* @throws {Error} When the workspace has no declarations deployed
|
|
166
|
+
*/
|
|
167
|
+
export declare function syncLocal(repoPath: string, ws: string, options?: LocalSyncOptions): Promise<FilesSyncReport>;
|
|
168
|
+
/**
|
|
169
|
+
* A workspace's Files: its declarations, its bindings and its last sync.
|
|
170
|
+
*
|
|
171
|
+
* @param repoPath - The repository
|
|
172
|
+
* @param ws - The workspace
|
|
173
|
+
* @returns Its status
|
|
174
|
+
*/
|
|
175
|
+
export declare function statusLocal(repoPath: string, ws: string): FilesStatus;
|
|
176
|
+
//# sourceMappingURL=files-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-local.d.ts","sourceRoot":"","sources":["../../src/files-local.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Files on a local repository: what `e3-cloud files` does given a
|
|
7
|
+
* repository's path.
|
|
8
|
+
*
|
|
9
|
+
* What a repository keeps of one workspace's Files is a file in the
|
|
10
|
+
* repository, `<repo>/.e3-cloud/files/<workspace>.json`: the declarations
|
|
11
|
+
* deployed to the workspace, where each source is bound, what each input
|
|
12
|
+
* took last, and the last sync's report. It belongs to the repository, never
|
|
13
|
+
* to the project, so removing the repository removes it, with the bytes the
|
|
14
|
+
* syncs took in.
|
|
15
|
+
*
|
|
16
|
+
* A sync reads each source with the developer's own cloud credentials (the
|
|
17
|
+
* binding's profile, else the SDK's usual chain) and writes the inputs
|
|
18
|
+
* through e3's own dataset writes, so the repository holds what a deployed
|
|
19
|
+
* workspace's sync would.
|
|
20
|
+
*/
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
22
|
+
import { dirname, join, resolve } from 'node:path';
|
|
23
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
24
|
+
import { ArrayType, DictType, OptionType, StringType, StructType, decodeJSONFor, encodeJSONFor, equalFor, none, some, } from '@elaraai/east';
|
|
25
|
+
import { LocalStorage, repoGet, repositoryOpen, workspaceGetPackage } from '@elaraai/e3-core';
|
|
26
|
+
import { nameProblem } from '@elaraai/e3-types';
|
|
27
|
+
import { FilesBindingType, FilesLedgerType, FilesManifestType, FilesMappingType, FilesSyncReportType, } from '@elaraai/e3-cloud-types';
|
|
28
|
+
import { checkBindings, checkFiles, parseBucketUrl, readPackageInputs } from '@elaraai/e3-cloud-files/check';
|
|
29
|
+
import { FilesSyncError, NO_LEDGER, ledgerStateOf, ledgerValueOf, syncFiles } from '@elaraai/e3-cloud-files/sync';
|
|
30
|
+
import { storageWriter } from '@elaraai/e3-cloud-files/storage';
|
|
31
|
+
import { s3FilesReader } from '@elaraai/e3-cloud-files/s3';
|
|
32
|
+
/** What a local repository keeps of one workspace's Files. */
|
|
33
|
+
export const LocalFilesStateType = StructType({
|
|
34
|
+
/** The declarations deployed to the workspace */
|
|
35
|
+
manifest: OptionType(FilesManifestType),
|
|
36
|
+
/** Where each source is bound */
|
|
37
|
+
bindings: ArrayType(FilesBindingType),
|
|
38
|
+
/** What each input took last, by input */
|
|
39
|
+
ledgers: DictType(StringType, FilesLedgerType),
|
|
40
|
+
/** The last sync's report; a dry run's is never kept */
|
|
41
|
+
lastSync: OptionType(FilesSyncReportType),
|
|
42
|
+
});
|
|
43
|
+
const encodeState = encodeJSONFor(LocalFilesStateType);
|
|
44
|
+
const decodeState = decodeJSONFor(LocalFilesStateType);
|
|
45
|
+
const sameMapping = equalFor(FilesMappingType);
|
|
46
|
+
/**
|
|
47
|
+
* Opens a local repository, as e3's CLI does: refused when this e3 cannot
|
|
48
|
+
* read it, upgraded in place when an older release wrote it.
|
|
49
|
+
*
|
|
50
|
+
* @param repoArg - The repository's path
|
|
51
|
+
* @returns Its absolute path
|
|
52
|
+
* @throws {Error} When there is no repository there, or this e3 cannot open it
|
|
53
|
+
*/
|
|
54
|
+
export async function openLocalRepository(repoArg) {
|
|
55
|
+
const path = repoGet(resolve(repoArg));
|
|
56
|
+
await repositoryOpen(new LocalStorage(), path);
|
|
57
|
+
return path;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Where a repository keeps a workspace's Files.
|
|
61
|
+
*
|
|
62
|
+
* @throws {Error} When the name is no workspace's
|
|
63
|
+
*/
|
|
64
|
+
export function statePath(repoPath, ws) {
|
|
65
|
+
const reason = nameProblem('workspace', ws);
|
|
66
|
+
if (reason !== null)
|
|
67
|
+
throw new Error(`'${ws}' is no workspace's name: ${reason}`);
|
|
68
|
+
return join(repoPath, '.e3-cloud', 'files', `${ws}.json`);
|
|
69
|
+
}
|
|
70
|
+
/** What a repository keeps of a workspace's Files: nothing yet, before its first deploy. */
|
|
71
|
+
export function readState(repoPath, ws) {
|
|
72
|
+
const path = statePath(repoPath, ws);
|
|
73
|
+
if (!existsSync(path))
|
|
74
|
+
return { manifest: none, bindings: [], ledgers: new Map(), lastSync: none };
|
|
75
|
+
try {
|
|
76
|
+
return decodeState(readFileSync(path));
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
throw new Error(`${path} cannot be read (${err instanceof Error ? err.message : String(err)}): remove it, then deploy the declarations and bind the sources again`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Keeps a workspace's Files, replacing the file whole so a reader never sees half of it. */
|
|
83
|
+
export function writeState(repoPath, ws, state) {
|
|
84
|
+
const path = statePath(repoPath, ws);
|
|
85
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
86
|
+
const partial = `${path}.${process.pid}.partial`;
|
|
87
|
+
writeFileSync(partial, encodeState(state));
|
|
88
|
+
renameSync(partial, path);
|
|
89
|
+
}
|
|
90
|
+
/** The ledger over the repository's file: each write keeps what an input took the moment it is written. */
|
|
91
|
+
export function stateLedger(repoPath, ws) {
|
|
92
|
+
return {
|
|
93
|
+
read(input) {
|
|
94
|
+
const ledger = readState(repoPath, ws).ledgers.get(input);
|
|
95
|
+
return Promise.resolve(ledger === undefined ? NO_LEDGER : ledgerStateOf(ledger));
|
|
96
|
+
},
|
|
97
|
+
write(input, taken) {
|
|
98
|
+
const state = readState(repoPath, ws);
|
|
99
|
+
const ledgers = new Map(state.ledgers);
|
|
100
|
+
ledgers.set(input, ledgerValueOf(taken));
|
|
101
|
+
writeState(repoPath, ws, { ...state, ledgers });
|
|
102
|
+
return Promise.resolve();
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A reader whose failures name the source, where it is bound and the profile
|
|
108
|
+
* it reads with: an expired login, a denied read or a missing bucket says
|
|
109
|
+
* which binding it was.
|
|
110
|
+
*/
|
|
111
|
+
function naming(reader, binding) {
|
|
112
|
+
const where = `source ${binding.source} (${binding.url}${binding.profile.type === 'some' ? `, profile ${binding.profile.value}` : ''})`;
|
|
113
|
+
const fail = (err) => {
|
|
114
|
+
throw new Error(`${where}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
async *list(prefix) {
|
|
118
|
+
try {
|
|
119
|
+
for await (const object of reader.list(prefix))
|
|
120
|
+
yield object;
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
fail(err);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
stat: (key) => reader.stat(key).catch(fail),
|
|
127
|
+
read: (key) => reader.read(key).catch(fail),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Reads each bound source's bucket with the developer's credentials: the
|
|
132
|
+
* binding's profile, else the SDK's usual chain (`AWS_PROFILE`, the
|
|
133
|
+
* environment, SSO). A bucket in another region than the one configured is
|
|
134
|
+
* followed there. A failure names the binding.
|
|
135
|
+
*
|
|
136
|
+
* @returns A reader for each binding, one client per profile and region
|
|
137
|
+
*/
|
|
138
|
+
export function s3Readers() {
|
|
139
|
+
const clients = new Map();
|
|
140
|
+
return (binding) => {
|
|
141
|
+
const location = parseBucketUrl(binding.url);
|
|
142
|
+
if ('problem' in location)
|
|
143
|
+
throw new Error(`source ${binding.source}: '${binding.url}' ${location.problem}`);
|
|
144
|
+
const profile = binding.profile.type === 'some' ? binding.profile.value : undefined;
|
|
145
|
+
const region = binding.region.type === 'some' ? binding.region.value : (process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION);
|
|
146
|
+
const key = `${profile ?? ''}\n${region ?? ''}`;
|
|
147
|
+
let client = clients.get(key);
|
|
148
|
+
if (client === undefined)
|
|
149
|
+
clients.set(key, client = new S3Client({ profile, region, followRegionRedirects: true }));
|
|
150
|
+
return naming(s3FilesReader(client, location), binding);
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/** The package a workspace runs, and its inputs. */
|
|
154
|
+
async function packageInputs(storage, repoPath, ws) {
|
|
155
|
+
const pkg = await workspaceGetPackage(storage, repoPath, ws);
|
|
156
|
+
const inputs = await readPackageInputs((hash) => storage.objects.read(repoPath, hash), pkg.hash);
|
|
157
|
+
return { pkg: { name: pkg.name, version: pkg.version }, inputs };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Deploys declarations to a workspace, checked against the package it runs.
|
|
161
|
+
* An input whose declaration changed is taken again whole by the next sync.
|
|
162
|
+
*
|
|
163
|
+
* @param repoPath - The repository ({@link openLocalRepository})
|
|
164
|
+
* @param ws - The workspace
|
|
165
|
+
* @param manifest - The declarations
|
|
166
|
+
* @param options - `dryRun`: check them, and keep nothing
|
|
167
|
+
* @returns The package, every problem, and the inputs taken again
|
|
168
|
+
*/
|
|
169
|
+
export async function deployLocal(repoPath, ws, manifest, options = {}) {
|
|
170
|
+
const storage = new LocalStorage();
|
|
171
|
+
const { pkg, inputs } = await packageInputs(storage, repoPath, ws);
|
|
172
|
+
const problems = checkFiles(manifest, inputs);
|
|
173
|
+
const state = readState(repoPath, ws);
|
|
174
|
+
const previous = state.manifest.type === 'some' ? state.manifest.value.mappings : [];
|
|
175
|
+
const retaken = [...state.ledgers.keys()].filter((input) => {
|
|
176
|
+
const was = previous.find((m) => m.input === input);
|
|
177
|
+
const now = manifest.mappings.find((m) => m.input === input);
|
|
178
|
+
return was === undefined || now === undefined || !sameMapping(was, now);
|
|
179
|
+
});
|
|
180
|
+
if (problems.length === 0 && options.dryRun !== true) {
|
|
181
|
+
const ledgers = new Map([...state.ledgers].filter(([input]) => !retaken.includes(input)));
|
|
182
|
+
writeState(repoPath, ws, { ...state, manifest: some(manifest), ledgers });
|
|
183
|
+
}
|
|
184
|
+
return { package: pkg, problems, retaken: retaken.filter((input) => manifest.mappings.some((m) => m.input === input)) };
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Binds a source to where its files are, for a workspace. A binding moved to
|
|
188
|
+
* another URL has its inputs taken again whole by the next sync.
|
|
189
|
+
*
|
|
190
|
+
* @param repoPath - The repository
|
|
191
|
+
* @param ws - The workspace
|
|
192
|
+
* @param binding - The binding
|
|
193
|
+
* @returns Every problem, and the inputs taken again
|
|
194
|
+
* @throws {Error} When the workspace has no declarations deployed
|
|
195
|
+
*/
|
|
196
|
+
export function bindLocal(repoPath, ws, binding) {
|
|
197
|
+
const state = readState(repoPath, ws);
|
|
198
|
+
if (state.manifest.type === 'none')
|
|
199
|
+
throw new Error(`${ws} has no Files declarations: deploy them first (e3-cloud files deploy)`);
|
|
200
|
+
const problems = checkBindings(state.manifest.value, [binding], { local: true });
|
|
201
|
+
if (problems.length > 0)
|
|
202
|
+
return { problems, retaken: [] };
|
|
203
|
+
const previous = state.bindings.find((b) => b.source === binding.source);
|
|
204
|
+
const retaken = previous !== undefined && previous.url !== binding.url
|
|
205
|
+
? state.manifest.value.mappings.filter((m) => m.source === binding.source && state.ledgers.has(m.input)).map((m) => m.input)
|
|
206
|
+
: [];
|
|
207
|
+
const ledgers = new Map([...state.ledgers].filter(([input]) => !retaken.includes(input)));
|
|
208
|
+
const bindings = previous === undefined ? [...state.bindings, binding] : state.bindings.map((b) => (b.source === binding.source ? binding : b));
|
|
209
|
+
writeState(repoPath, ws, { ...state, bindings, ledgers });
|
|
210
|
+
return { problems: [], retaken };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Syncs a workspace's inputs with their sources' files. The declarations are
|
|
214
|
+
* checked again first, against the package the workspace runs now.
|
|
215
|
+
*
|
|
216
|
+
* @param repoPath - The repository
|
|
217
|
+
* @param ws - The workspace
|
|
218
|
+
* @param options - Which inputs, whether a dry run, and the reader
|
|
219
|
+
* @returns What it did, per input
|
|
220
|
+
* @throws {FilesSyncError} When the declarations no longer fit the package, or
|
|
221
|
+
* a source is not bound, before anything is read
|
|
222
|
+
* @throws {Error} When the workspace has no declarations deployed
|
|
223
|
+
*/
|
|
224
|
+
export async function syncLocal(repoPath, ws, options = {}) {
|
|
225
|
+
const storage = new LocalStorage();
|
|
226
|
+
const state = readState(repoPath, ws);
|
|
227
|
+
if (state.manifest.type === 'none')
|
|
228
|
+
throw new Error(`${ws} has no Files declarations: deploy them first (e3-cloud files deploy)`);
|
|
229
|
+
const manifest = state.manifest.value;
|
|
230
|
+
const { inputs } = await packageInputs(storage, repoPath, ws);
|
|
231
|
+
const problems = checkFiles(manifest, inputs);
|
|
232
|
+
if (problems.length > 0)
|
|
233
|
+
throw new FilesSyncError(problems);
|
|
234
|
+
const report = await syncFiles({
|
|
235
|
+
manifest,
|
|
236
|
+
bindings: state.bindings,
|
|
237
|
+
reader: options.reader ?? s3Readers(),
|
|
238
|
+
writer: storageWriter(storage, repoPath, ws),
|
|
239
|
+
ledger: stateLedger(repoPath, ws),
|
|
240
|
+
dryRun: options.dryRun,
|
|
241
|
+
inputs: options.inputs,
|
|
242
|
+
});
|
|
243
|
+
if (options.dryRun !== true)
|
|
244
|
+
writeState(repoPath, ws, { ...readState(repoPath, ws), lastSync: some(report) });
|
|
245
|
+
return report;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* A workspace's Files: its declarations, its bindings and its last sync.
|
|
249
|
+
*
|
|
250
|
+
* @param repoPath - The repository
|
|
251
|
+
* @param ws - The workspace
|
|
252
|
+
* @returns Its status
|
|
253
|
+
*/
|
|
254
|
+
export function statusLocal(repoPath, ws) {
|
|
255
|
+
const { manifest, bindings, lastSync } = readState(repoPath, ws);
|
|
256
|
+
return { manifest, bindings, lastSync };
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=files-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-local.js","sourceRoot":"","sources":["../../src/files-local.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { type FilesManifest } from '@elaraai/e3-cloud-types';
|
|
6
|
+
/**
|
|
7
|
+
* The declarations a source file's default export holds.
|
|
8
|
+
*
|
|
9
|
+
* @param file - The source: a module whose default export is `Files.manifest(...)`
|
|
10
|
+
* @returns The declarations
|
|
11
|
+
* @throws {Error} When the source does not bundle or run, the project has no
|
|
12
|
+
* `@elaraai/e3-cloud-files`, or its default export is no declarations
|
|
13
|
+
*/
|
|
14
|
+
export declare function filesFromSource(file: string): Promise<FilesManifest>;
|
|
15
|
+
//# sourceMappingURL=files-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-source.d.ts","sourceRoot":"","sources":["../../src/files-source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAWhF;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAU1E"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Files' declarations from a solution's source: what `e3-cloud files deploy`
|
|
7
|
+
* deploys. The source is run as `e3-cloud app` runs an app's
|
|
8
|
+
* (`source-module.ts`), and its default export must be `Files.manifest(...)`
|
|
9
|
+
* of the project's own `@elaraai/e3-cloud-files`.
|
|
10
|
+
*/
|
|
11
|
+
import { decodeBeast2For, encodeBeast2For } from '@elaraai/east';
|
|
12
|
+
import { FilesManifestType } from '@elaraai/e3-cloud-types';
|
|
13
|
+
import { resolveSource, sourceDefaultExport } from './source-module.js';
|
|
14
|
+
const encodeManifest = encodeBeast2For(FilesManifestType);
|
|
15
|
+
const decodeManifest = decodeBeast2For(FilesManifestType);
|
|
16
|
+
/** What a default export that is no declarations is told. */
|
|
17
|
+
function notDeclarations(file) {
|
|
18
|
+
return new Error(`${file}'s default export must be Files' declarations:\n\n export default Files.manifest([upload]);\n`);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The declarations a source file's default export holds.
|
|
22
|
+
*
|
|
23
|
+
* @param file - The source: a module whose default export is `Files.manifest(...)`
|
|
24
|
+
* @returns The declarations
|
|
25
|
+
* @throws {Error} When the source does not bundle or run, the project has no
|
|
26
|
+
* `@elaraai/e3-cloud-files`, or its default export is no declarations
|
|
27
|
+
*/
|
|
28
|
+
export async function filesFromSource(file) {
|
|
29
|
+
const { path } = resolveSource(file, '@elaraai/e3-cloud-files', 'files are declared');
|
|
30
|
+
const exported = await sourceDefaultExport(file, path);
|
|
31
|
+
if (typeof exported !== 'object' || exported === null || !('sources' in exported) || !('mappings' in exported))
|
|
32
|
+
throw notDeclarations(file);
|
|
33
|
+
try {
|
|
34
|
+
// Read back as this CLI's type, so declarations of another shape are refused here
|
|
35
|
+
return decodeManifest(encodeManifest(exported));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw notDeclarations(file);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=files-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-source.js","sourceRoot":"","sources":["../../src/files-source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAsB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAExE,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;AAC1D,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC;AAE1D,6DAA6D;AAC7D,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,KAAK,CAAC,GAAG,IAAI,gGAAgG,CAAC,CAAC;AAC5H,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,yBAAyB,EAAE,oBAAoB,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC;QAAE,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5I,IAAI,CAAC;QACH,kFAAkF;QAClF,OAAO,cAAc,CAAC,cAAc,CAAC,QAAyB,CAAC,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A source's entry, resolved, and a package of its project's.
|
|
7
|
+
*
|
|
8
|
+
* @param file - The source
|
|
9
|
+
* @param entry - The package the project must have, e.g. `@elaraai/e3-cloud-ui`
|
|
10
|
+
* @param why - What it is needed for, completing "… is built with the version its source imports"
|
|
11
|
+
* @returns The source's absolute path, and the package's entry, as the source's project resolves it
|
|
12
|
+
* @throws {Error} When the source does not exist, or its project lacks the package
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveSource(file: string, entry: string, why: string): {
|
|
15
|
+
path: string;
|
|
16
|
+
entryPath: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Runs a source module and answers its default export.
|
|
20
|
+
*
|
|
21
|
+
* @param file - The source, as the user named it (for messages)
|
|
22
|
+
* @param path - Its absolute path ({@link resolveSource})
|
|
23
|
+
* @returns Its default export
|
|
24
|
+
* @throws {Error} When it does not bundle or does not run
|
|
25
|
+
*/
|
|
26
|
+
export declare function sourceDefaultExport(file: string, path: string): Promise<unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Imports a package by the entry a source's project resolves it to.
|
|
29
|
+
*
|
|
30
|
+
* @param entryPath - The entry ({@link resolveSource})
|
|
31
|
+
* @returns The module
|
|
32
|
+
*/
|
|
33
|
+
export declare function importEntry<T>(entryPath: string): Promise<T>;
|
|
34
|
+
//# sourceMappingURL=source-module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-module.d.ts","sourceRoot":"","sources":["../../src/source-module.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAQ3G;AAiBD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBtF;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAElE"}
|