@platforma-sdk/block-tools 2.1.11 → 2.3.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/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +113 -71
- package/dist/cli.mjs.map +1 -1
- package/dist/cmd/index.d.ts +2 -0
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/publish.d.ts +11 -0
- package/dist/cmd/publish.d.ts.map +1 -0
- package/dist/config-B1U40s2a.js +3 -0
- package/dist/config-B1U40s2a.js.map +1 -0
- package/dist/config-YukCegnp.mjs +1587 -0
- package/dist/config-YukCegnp.mjs.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +170 -38
- package/dist/index.mjs.map +1 -1
- package/dist/io/folder_reader.d.ts +24 -0
- package/dist/io/folder_reader.d.ts.map +1 -0
- package/dist/io/index.d.ts +3 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/storage.d.ts.map +1 -0
- package/dist/lib.d.ts +1 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/registry_v1/config_schema.d.ts +13 -13
- package/dist/registry_v1/registry.d.ts +1 -1
- package/dist/registry_v1/registry.d.ts.map +1 -1
- package/dist/registry_v1/v1_repo_schema.d.ts +1 -1
- package/dist/registry_v1/v1_repo_schema.d.ts.map +1 -1
- package/dist/v2/build_dist.d.ts +2 -1
- package/dist/v2/build_dist.d.ts.map +1 -1
- package/dist/v2/index.d.ts +1 -0
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/model/block_components.d.ts +170 -178
- package/dist/v2/model/block_components.d.ts.map +1 -1
- package/dist/v2/model/block_description.d.ts +2873 -0
- package/dist/v2/model/block_description.d.ts.map +1 -0
- package/dist/v2/model/{meta.d.ts → block_meta.d.ts} +555 -3
- package/dist/v2/model/block_meta.d.ts.map +1 -0
- package/dist/v2/model/content_conversion.d.ts +7 -2
- package/dist/v2/model/content_conversion.d.ts.map +1 -1
- package/dist/v2/model/index.d.ts +3 -2079
- package/dist/v2/model/index.d.ts.map +1 -1
- package/dist/v2/registry/index.d.ts +4 -0
- package/dist/v2/registry/index.d.ts.map +1 -0
- package/dist/v2/registry/registry.d.ts +16 -0
- package/dist/v2/registry/registry.d.ts.map +1 -0
- package/dist/v2/registry/registry_reader.d.ts +12 -0
- package/dist/v2/registry/registry_reader.d.ts.map +1 -0
- package/dist/v2/registry/schema_internal.d.ts +7 -0
- package/dist/v2/registry/schema_internal.d.ts.map +1 -0
- package/dist/v2/registry/schema_public.d.ts +4499 -0
- package/dist/v2/registry/schema_public.d.ts.map +1 -0
- package/package.json +8 -5
- package/src/cmd/build-meta.ts +2 -2
- package/src/cmd/index.ts +2 -0
- package/src/cmd/publish.ts +69 -0
- package/src/io/folder_reader.test.ts +21 -0
- package/src/io/folder_reader.ts +77 -0
- package/src/io/index.ts +2 -0
- package/src/lib.ts +1 -0
- package/src/registry_v1/config.ts +1 -1
- package/src/registry_v1/registry.test.ts +1 -1
- package/src/registry_v1/registry.ts +1 -1
- package/src/registry_v1/v1_repo_schema.ts +1 -1
- package/src/v2/build_dist.ts +16 -12
- package/src/v2/index.ts +1 -0
- package/src/v2/model/block_components.ts +14 -10
- package/src/v2/model/block_description.ts +49 -0
- package/src/v2/model/{meta.ts → block_meta.ts} +23 -5
- package/src/v2/model/content_conversion.ts +78 -10
- package/src/v2/model/index.ts +3 -44
- package/src/v2/registry/index.ts +3 -0
- package/src/v2/registry/registry.ts +240 -0
- package/src/v2/registry/registry_reader.ts +71 -0
- package/src/v2/registry/schema_internal.ts +13 -0
- package/src/v2/registry/schema_public.ts +112 -0
- package/dist/config-Br5DwFuM.mjs +0 -1317
- package/dist/config-Br5DwFuM.mjs.map +0 -1
- package/dist/config-DMAm68Pm.js +0 -3
- package/dist/config-DMAm68Pm.js.map +0 -1
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/v2/model/common.d.ts +0 -3
- package/dist/v2/model/common.d.ts.map +0 -1
- package/dist/v2/model/content_types.d.ts +0 -478
- package/dist/v2/model/content_types.d.ts.map +0 -1
- package/dist/v2/model/meta.d.ts.map +0 -1
- package/dist/v2/registry/schema.d.ts +0 -15
- package/dist/v2/registry/schema.d.ts.map +0 -1
- package/src/v2/model/common.ts +0 -2
- package/src/v2/model/content_types.ts +0 -233
- package/src/v2/registry/schema.ts +0 -29
- /package/dist/{lib → io}/storage.d.ts +0 -0
- /package/src/{lib → io}/storage.test.ts +0 -0
- /package/src/{lib → io}/storage.ts +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { MiLogger } from '@milaboratories/ts-helpers';
|
|
2
|
+
import { compare as compareSemver, satisfies } from 'semver';
|
|
3
|
+
import { RegistryStorage } from '../../io/storage';
|
|
4
|
+
import { BlockPackIdNoVersion, BlockPackManifest } from '@milaboratories/pl-model-middle-layer';
|
|
5
|
+
import {
|
|
6
|
+
GlobalUpdateSeedInFile,
|
|
7
|
+
GlobalUpdateSeedOutFile,
|
|
8
|
+
PackageUpdatePattern,
|
|
9
|
+
packageUpdateSeedPath,
|
|
10
|
+
VersionUpdatesPrefix
|
|
11
|
+
} from './schema_internal';
|
|
12
|
+
import {
|
|
13
|
+
GlobalOverviewReg,
|
|
14
|
+
GlobalOverviewPath,
|
|
15
|
+
ManifestSuffix,
|
|
16
|
+
packageContentPrefix,
|
|
17
|
+
PackageOverview,
|
|
18
|
+
packageOverviewPath,
|
|
19
|
+
ManifestFileName
|
|
20
|
+
} from './schema_public';
|
|
21
|
+
import { BlockPackDescriptionManifestAddRelativePathPrefix, RelativeContentReader } from '../model';
|
|
22
|
+
import { randomUUID } from 'node:crypto';
|
|
23
|
+
|
|
24
|
+
type PackageUpdateInfo = {
|
|
25
|
+
package: BlockPackIdNoVersion;
|
|
26
|
+
versions: Set<String>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export class BlockRegistryV2 {
|
|
30
|
+
constructor(
|
|
31
|
+
private readonly storage: RegistryStorage,
|
|
32
|
+
private readonly logger?: MiLogger
|
|
33
|
+
) {}
|
|
34
|
+
|
|
35
|
+
private async updateRegistry() {
|
|
36
|
+
this.logger?.info('Initiating registry refresh...');
|
|
37
|
+
|
|
38
|
+
// reading update requests
|
|
39
|
+
const packagesToUpdate = new Map<string, PackageUpdateInfo>();
|
|
40
|
+
const seedPaths: string[] = [];
|
|
41
|
+
const rawSeedPaths = await this.storage.listFiles(VersionUpdatesPrefix);
|
|
42
|
+
this.logger?.info('Packages to be updated:');
|
|
43
|
+
for (const seedPath of rawSeedPaths) {
|
|
44
|
+
const match = seedPath.match(PackageUpdatePattern);
|
|
45
|
+
if (!match) continue;
|
|
46
|
+
seedPaths.push(seedPath);
|
|
47
|
+
const { packageKeyWithoutVersion, organization, name, version, seed } = match.groups!;
|
|
48
|
+
|
|
49
|
+
let update = packagesToUpdate.get(packageKeyWithoutVersion);
|
|
50
|
+
let added = false;
|
|
51
|
+
if (!update) {
|
|
52
|
+
packagesToUpdate.set(packageKeyWithoutVersion, {
|
|
53
|
+
package: { organization, name },
|
|
54
|
+
versions: new Set([version])
|
|
55
|
+
});
|
|
56
|
+
added = true;
|
|
57
|
+
} else if (!update.versions.has(version)) {
|
|
58
|
+
update.versions.add(version);
|
|
59
|
+
added = true;
|
|
60
|
+
}
|
|
61
|
+
this.logger?.info(` - ${organization}:${name}:${version} added:${added}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// loading global overview
|
|
65
|
+
const overviewContent = await this.storage.getFile(GlobalOverviewPath);
|
|
66
|
+
const overview: GlobalOverviewReg =
|
|
67
|
+
overviewContent === undefined
|
|
68
|
+
? { schema: 'v2', packages: [] }
|
|
69
|
+
: GlobalOverviewReg.parse(JSON.parse(overviewContent.toString()));
|
|
70
|
+
let overviewPackages = overview.packages;
|
|
71
|
+
this.logger?.info(`Global overview loaded, ${overviewPackages.length} records`);
|
|
72
|
+
|
|
73
|
+
// updating packages
|
|
74
|
+
for (const [, packageInfo] of packagesToUpdate.entries()) {
|
|
75
|
+
// reading existing overview
|
|
76
|
+
const overviewFile = packageOverviewPath(packageInfo.package);
|
|
77
|
+
const pOverviewContent = await this.storage.getFile(overviewFile);
|
|
78
|
+
const packageOverview: PackageOverview =
|
|
79
|
+
pOverviewContent === undefined
|
|
80
|
+
? { schema: 'v2', versions: [] }
|
|
81
|
+
: PackageOverview.parse(JSON.parse(pOverviewContent.toString()));
|
|
82
|
+
this.logger?.info(
|
|
83
|
+
`Updating ${packageInfo.package.organization}:${packageInfo.package.name} overview, ${packageOverview.versions.length} records`
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// removing versions that we will update
|
|
87
|
+
const newVersions = packageOverview.versions.filter(
|
|
88
|
+
(e) => !packageInfo.versions.has(e.description.id.version)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// reading new entries
|
|
92
|
+
for (const [v] of packageInfo.versions.entries()) {
|
|
93
|
+
const version = v.toString();
|
|
94
|
+
const manifestContent = await this.storage.getFile(
|
|
95
|
+
packageContentPrefix({
|
|
96
|
+
...packageInfo.package,
|
|
97
|
+
version
|
|
98
|
+
}) + ManifestSuffix
|
|
99
|
+
);
|
|
100
|
+
if (!manifestContent) continue; // absent package
|
|
101
|
+
const sha256 = Buffer.from(await crypto.subtle.digest('sha-256', manifestContent))
|
|
102
|
+
.toString('hex')
|
|
103
|
+
.toUpperCase();
|
|
104
|
+
newVersions.push({
|
|
105
|
+
description: BlockPackDescriptionManifestAddRelativePathPrefix(version).parse(
|
|
106
|
+
BlockPackManifest.parse(JSON.parse(manifestContent.toString('utf8'))).description
|
|
107
|
+
),
|
|
108
|
+
manifestSha256: sha256
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// sorting entries according to version
|
|
113
|
+
newVersions.sort((e1, e2) =>
|
|
114
|
+
compareSemver(e2.description.id.version, e1.description.id.version)
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// write package overview back
|
|
118
|
+
await this.storage.putFile(
|
|
119
|
+
overviewFile,
|
|
120
|
+
Buffer.from(
|
|
121
|
+
JSON.stringify({ schema: 'v2', versions: newVersions } satisfies PackageOverview)
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
this.logger?.info(`Done (${newVersions.length} records)`);
|
|
125
|
+
|
|
126
|
+
// patching corresponding entry in overview
|
|
127
|
+
overviewPackages = overviewPackages.filter(
|
|
128
|
+
(e) =>
|
|
129
|
+
e.id.organization !== packageInfo.package.organization ||
|
|
130
|
+
e.id.name !== packageInfo.package.name
|
|
131
|
+
);
|
|
132
|
+
overviewPackages.push({
|
|
133
|
+
id: {
|
|
134
|
+
organization: packageInfo.package.organization,
|
|
135
|
+
name: packageInfo.package.name
|
|
136
|
+
},
|
|
137
|
+
allVersions: newVersions.map((e) => e.description.id.version).reverse(),
|
|
138
|
+
latest: BlockPackDescriptionManifestAddRelativePathPrefix(
|
|
139
|
+
`${packageInfo.package.organization}/${packageInfo.package.name}`
|
|
140
|
+
).parse(newVersions[0].description),
|
|
141
|
+
latestManifestSha256: newVersions[0].manifestSha256
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// writing global overview
|
|
146
|
+
await this.storage.putFile(
|
|
147
|
+
GlobalOverviewPath,
|
|
148
|
+
Buffer.from(
|
|
149
|
+
JSON.stringify({ schema: 'v2', packages: overviewPackages } satisfies GlobalOverviewReg)
|
|
150
|
+
)
|
|
151
|
+
);
|
|
152
|
+
this.logger?.info(`Global overview updated (${overviewPackages.length} records)`);
|
|
153
|
+
|
|
154
|
+
// deleting seeds
|
|
155
|
+
await this.storage.deleteFiles(...seedPaths.map((sp) => `${VersionUpdatesPrefix}${sp}`));
|
|
156
|
+
this.logger?.info(`Version update requests cleared`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public async updateIfNeeded(force: boolean = false): Promise<void> {
|
|
160
|
+
// implementation of main convergence algorithm
|
|
161
|
+
|
|
162
|
+
this.logger?.info(`Checking if registry requires refresh...`);
|
|
163
|
+
const updateRequestSeed = await this.storage.getFile(GlobalUpdateSeedInFile);
|
|
164
|
+
const currentUpdatedSeed = await this.storage.getFile(GlobalUpdateSeedOutFile);
|
|
165
|
+
if (!force && updateRequestSeed === undefined && currentUpdatedSeed === undefined) return;
|
|
166
|
+
if (
|
|
167
|
+
!force &&
|
|
168
|
+
updateRequestSeed !== undefined &&
|
|
169
|
+
currentUpdatedSeed !== undefined &&
|
|
170
|
+
updateRequestSeed.equals(currentUpdatedSeed)
|
|
171
|
+
)
|
|
172
|
+
return;
|
|
173
|
+
|
|
174
|
+
await this.updateRegistry();
|
|
175
|
+
|
|
176
|
+
if (updateRequestSeed) {
|
|
177
|
+
await this.storage.putFile(GlobalUpdateSeedOutFile, updateRequestSeed);
|
|
178
|
+
this.logger?.info(`Refresh finished`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public async getPackageOverview(
|
|
183
|
+
name: BlockPackIdNoVersion
|
|
184
|
+
): Promise<undefined | PackageOverview> {
|
|
185
|
+
const content = await this.storage.getFile(packageOverviewPath(name));
|
|
186
|
+
if (content === undefined) return undefined;
|
|
187
|
+
return PackageOverview.parse(JSON.parse(content.toString()));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public async getGlobalOverview(): Promise<undefined | GlobalOverviewReg> {
|
|
191
|
+
const content = await this.storage.getFile(GlobalOverviewPath);
|
|
192
|
+
if (content === undefined) return undefined;
|
|
193
|
+
return GlobalOverviewReg.parse(JSON.parse(content.toString()));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// public async getGlobalOverviewExplicitBytes(): Promise<undefined | GlobalOverviewReg> {
|
|
197
|
+
// const content = await this.storage.getFile(GlobalOverviewPath);
|
|
198
|
+
// if (content === undefined) return undefined;
|
|
199
|
+
// return GlobalOverviewReg.parse(JSON.parse(content.toString()));
|
|
200
|
+
// }
|
|
201
|
+
|
|
202
|
+
public async publishPackage(
|
|
203
|
+
manifest: BlockPackManifest,
|
|
204
|
+
fileReader: RelativeContentReader
|
|
205
|
+
): Promise<void> {
|
|
206
|
+
const prefix = packageContentPrefix(manifest.description.id);
|
|
207
|
+
// uploading content files
|
|
208
|
+
for (const f of manifest.files) {
|
|
209
|
+
const bytes = await fileReader(f.name);
|
|
210
|
+
if (bytes.length !== f.size)
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Actual file size don't match file size from the manifest file for ${f.name} (actual = ${bytes.length}; manifest = ${f.size})`
|
|
213
|
+
);
|
|
214
|
+
const sha256 = Buffer.from(await crypto.subtle.digest('sha-256', bytes))
|
|
215
|
+
.toString('hex')
|
|
216
|
+
.toUpperCase();
|
|
217
|
+
if (sha256 !== f.sha256.toUpperCase())
|
|
218
|
+
throw new Error(
|
|
219
|
+
`Actual file SHA-256 don't match the checksum from the manifest file for ${f.name} (actual = ${sha256}; manifest = ${f.sha256.toUpperCase()})`
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const dst = prefix + '/' + f.name;
|
|
223
|
+
this.logger?.info(`Uploading ${f.name} -> ${dst} ...`);
|
|
224
|
+
await this.storage.putFile(dst, bytes);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// uploading manifest as the last upload action
|
|
228
|
+
const manifestDst = prefix + '/' + ManifestFileName;
|
|
229
|
+
this.logger?.info(`Uploading manifest to ${manifestDst} ...`);
|
|
230
|
+
await this.storage.putFile(manifestDst, Buffer.from(JSON.stringify(manifest)));
|
|
231
|
+
|
|
232
|
+
// adding update seed
|
|
233
|
+
const seed = randomUUID();
|
|
234
|
+
const seedPath = packageUpdateSeedPath(manifest.description.id, seed);
|
|
235
|
+
this.logger?.info(`Creating update seed at ${seedPath} ...`);
|
|
236
|
+
await this.storage.putFile(seedPath, Buffer.from(seed));
|
|
237
|
+
this.logger?.info(`Touching global update seed ${GlobalUpdateSeedInFile} ...`);
|
|
238
|
+
await this.storage.putFile(GlobalUpdateSeedInFile, Buffer.from(seed));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockPackDescriptionManifest,
|
|
3
|
+
BlockPackMetaEmbeddedBytes,
|
|
4
|
+
BlockPackMetaManifest,
|
|
5
|
+
BlockPackOverview
|
|
6
|
+
} from '@milaboratories/pl-model-middle-layer';
|
|
7
|
+
import { FolderReader } from '../../io';
|
|
8
|
+
import canonicalize from 'canonicalize';
|
|
9
|
+
import {
|
|
10
|
+
GlobalOverview,
|
|
11
|
+
GlobalOverviewEntryReg,
|
|
12
|
+
GlobalOverviewFileName,
|
|
13
|
+
GlobalOverviewReg,
|
|
14
|
+
MainPrefix,
|
|
15
|
+
ManifestFileName
|
|
16
|
+
} from './schema_public';
|
|
17
|
+
import { BlockPackMetaEmbedBytes } from '../model';
|
|
18
|
+
|
|
19
|
+
export type BlockPackOverviewNoRegLabel = Omit<BlockPackOverview, 'registryId'>;
|
|
20
|
+
|
|
21
|
+
export class RegistryV2Reader {
|
|
22
|
+
private readonly metaCache = new Map<
|
|
23
|
+
string,
|
|
24
|
+
{ sha256: string; meta: BlockPackMetaEmbeddedBytes }
|
|
25
|
+
>();
|
|
26
|
+
|
|
27
|
+
private readonly rootFolderReader: FolderReader;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
private readonly url: string,
|
|
31
|
+
reader: FolderReader
|
|
32
|
+
) {
|
|
33
|
+
this.rootFolderReader = reader.relativeReader(MainPrefix);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async embedMetaContent(
|
|
37
|
+
entry: GlobalOverviewEntryReg
|
|
38
|
+
): Promise<BlockPackMetaEmbeddedBytes> {
|
|
39
|
+
const id = canonicalize(entry.id)!;
|
|
40
|
+
const fromCache = this.metaCache.get(id);
|
|
41
|
+
if (fromCache && fromCache.sha256 === entry.latestManifestSha256) return fromCache.meta;
|
|
42
|
+
const rootContentReader = this.rootFolderReader.getContentReader();
|
|
43
|
+
const meta = await BlockPackMetaEmbedBytes(rootContentReader).parseAsync(entry.latest.meta);
|
|
44
|
+
this.metaCache.set(id, { sha256: entry.latestManifestSha256, meta });
|
|
45
|
+
return meta;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public async listBlockPacks(): Promise<BlockPackOverviewNoRegLabel[]> {
|
|
49
|
+
const rootContentReader = this.rootFolderReader.getContentReader();
|
|
50
|
+
const globalOverview = GlobalOverviewReg.parse(
|
|
51
|
+
JSON.parse(
|
|
52
|
+
Buffer.from(await this.rootFolderReader.readFile(GlobalOverviewFileName)).toString()
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
return await Promise.all(
|
|
56
|
+
globalOverview.packages.map(
|
|
57
|
+
async (p) =>
|
|
58
|
+
({
|
|
59
|
+
id: p.latest.id,
|
|
60
|
+
meta: await this.embedMetaContent(p),
|
|
61
|
+
spec: {
|
|
62
|
+
type: 'from-registry-v2',
|
|
63
|
+
id: p.latest.id,
|
|
64
|
+
registryUrl: this.url
|
|
65
|
+
},
|
|
66
|
+
otherVersions: p.allVersions
|
|
67
|
+
}) satisfies BlockPackOverviewNoRegLabel
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BlockPackId } from '@milaboratories/pl-model-middle-layer';
|
|
2
|
+
|
|
3
|
+
export const VersionUpdatesPrefix = '_updates_v2/per_package_version/';
|
|
4
|
+
|
|
5
|
+
export function packageUpdateSeedPath(bp: BlockPackId, seed: string): string {
|
|
6
|
+
return `${VersionUpdatesPrefix}${bp.organization}/${bp.name}/${bp.version}/${seed}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const PackageUpdatePattern =
|
|
10
|
+
/(?<packageKeyWithoutVersion>(?<organization>[^\/]+)\/(?<name>[^\/]+))\/(?<version>[^\/]+)\/(?<seed>[^\/]+)$/;
|
|
11
|
+
|
|
12
|
+
export const GlobalUpdateSeedInFile = '_updates_v2/_global_update_in';
|
|
13
|
+
export const GlobalUpdateSeedOutFile = '_updates_v2/_global_update_out';
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockComponentsManifest,
|
|
3
|
+
BlockPackDescriptionManifest,
|
|
4
|
+
BlockPackId,
|
|
5
|
+
BlockPackIdNoVersion,
|
|
6
|
+
BlockPackMeta,
|
|
7
|
+
ContentRelativeBinary,
|
|
8
|
+
ContentRelativeText,
|
|
9
|
+
CreateBlockPackDescriptionSchema,
|
|
10
|
+
SemVer,
|
|
11
|
+
Sha256Schema
|
|
12
|
+
} from '@milaboratories/pl-model-middle-layer';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { RelativeContentReader, relativeToExplicitBytes, relativeToExplicitString } from '../model';
|
|
15
|
+
|
|
16
|
+
export const MainPrefix = 'v2/';
|
|
17
|
+
|
|
18
|
+
export const GlobalOverviewFileName = 'overview.json';
|
|
19
|
+
export const PackageOverviewFileName = 'overview.json';
|
|
20
|
+
export const ManifestFileName = 'manifest.json';
|
|
21
|
+
|
|
22
|
+
export function packageContentPrefix(bp: BlockPackId): string {
|
|
23
|
+
return `${MainPrefix}${bp.organization}/${bp.name}/${bp.version}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const ManifestSuffix = '/' + ManifestFileName;
|
|
27
|
+
|
|
28
|
+
// export function payloadFilePath(bp: BlockPackId, file: string): string {
|
|
29
|
+
// return `${MainPrefix}${bp.organization}/${bp.name}/${bp.version}/${file}`;
|
|
30
|
+
// }
|
|
31
|
+
|
|
32
|
+
export const PackageOverviewVersionEntry = z.object({
|
|
33
|
+
description: BlockPackDescriptionManifest,
|
|
34
|
+
manifestSha256: Sha256Schema
|
|
35
|
+
});
|
|
36
|
+
export type PackageOverviewVersionEntry = z.infer<typeof PackageOverviewVersionEntry>;
|
|
37
|
+
|
|
38
|
+
export const PackageOverview = z.object({
|
|
39
|
+
schema: z.literal('v2'),
|
|
40
|
+
versions: z.array(PackageOverviewVersionEntry)
|
|
41
|
+
});
|
|
42
|
+
export type PackageOverview = z.infer<typeof PackageOverview>;
|
|
43
|
+
|
|
44
|
+
export function packageOverviewPath(bp: BlockPackIdNoVersion): string {
|
|
45
|
+
return `${MainPrefix}${bp.organization}/${bp.name}/${PackageOverviewFileName}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const GlobalOverviewPath = `${MainPrefix}${GlobalOverviewFileName}`;
|
|
49
|
+
|
|
50
|
+
export function GlobalOverviewEntry<const Description extends z.ZodTypeAny>(
|
|
51
|
+
descriptionType: Description
|
|
52
|
+
) {
|
|
53
|
+
return z.object({
|
|
54
|
+
id: BlockPackIdNoVersion,
|
|
55
|
+
allVersions: z.array(z.string()),
|
|
56
|
+
latest: descriptionType,
|
|
57
|
+
latestManifestSha256: Sha256Schema
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export const GlobalOverviewEntryReg = GlobalOverviewEntry(BlockPackDescriptionManifest);
|
|
61
|
+
export type GlobalOverviewEntryReg = z.infer<typeof GlobalOverviewEntryReg>;
|
|
62
|
+
|
|
63
|
+
export function GlobalOverview<const Description extends z.ZodTypeAny>(
|
|
64
|
+
descriptionType: Description
|
|
65
|
+
) {
|
|
66
|
+
return z.object({
|
|
67
|
+
schema: z.literal('v2'),
|
|
68
|
+
packages: z.array(GlobalOverviewEntry(descriptionType))
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const GlobalOverviewReg = GlobalOverview(BlockPackDescriptionManifest);
|
|
73
|
+
export type GlobalOverviewReg = z.infer<typeof GlobalOverviewReg>;
|
|
74
|
+
|
|
75
|
+
export function BlockDescriptionToExplicitBinaryBytes(reader: RelativeContentReader) {
|
|
76
|
+
return CreateBlockPackDescriptionSchema(
|
|
77
|
+
BlockComponentsManifest,
|
|
78
|
+
BlockPackMeta(
|
|
79
|
+
ContentRelativeText.transform(relativeToExplicitString(reader)),
|
|
80
|
+
ContentRelativeBinary.transform(relativeToExplicitBytes(reader))
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
export function GlobalOverviewToExplicitBinaryBytes(reader: RelativeContentReader) {
|
|
85
|
+
return GlobalOverview(
|
|
86
|
+
CreateBlockPackDescriptionSchema(
|
|
87
|
+
BlockComponentsManifest,
|
|
88
|
+
BlockPackMeta(
|
|
89
|
+
ContentRelativeText.transform(relativeToExplicitString(reader)),
|
|
90
|
+
ContentRelativeBinary.transform(relativeToExplicitBytes(reader))
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
export type GlobalOverviewExplicitBinaryBytes = z.infer<
|
|
96
|
+
ReturnType<typeof GlobalOverviewToExplicitBinaryBytes>
|
|
97
|
+
>;
|
|
98
|
+
|
|
99
|
+
export function GlobalOverviewToExplicitBinaryBase64(reader: RelativeContentReader) {
|
|
100
|
+
return GlobalOverview(
|
|
101
|
+
CreateBlockPackDescriptionSchema(
|
|
102
|
+
BlockComponentsManifest,
|
|
103
|
+
BlockPackMeta(
|
|
104
|
+
ContentRelativeText.transform(relativeToExplicitString(reader)),
|
|
105
|
+
ContentRelativeBinary.transform(relativeToExplicitBytes(reader))
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
export type GlobalOverviewExplicitBinaryBase64 = z.infer<
|
|
111
|
+
ReturnType<typeof GlobalOverviewToExplicitBinaryBase64>
|
|
112
|
+
>;
|