@platforma-sdk/block-tools 2.6.44 → 2.6.45
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 +16 -9
- package/bin/dev.js +4 -4
- package/bin/run.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +16 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/cmd/index.d.ts +8 -8
- package/dist/cmd/mark-stable.d.ts +1 -1
- package/dist/cmd/publish.d.ts +1 -1
- package/dist/cmd/restore-overview-from-snapshot.d.ts +1 -1
- package/dist/{config-DKBY0B2u.mjs → config-Cc8_zV3b.mjs} +48 -17
- package/dist/config-Cc8_zV3b.mjs.map +1 -0
- package/dist/config-Ycas5fbX.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/dist/registry_v1/config_schema.d.ts +7 -7
- package/dist/registry_v1/v1_repo_schema.d.ts +1 -1
- package/dist/v2/model/block_components.d.ts +19 -19
- package/dist/v2/model/block_description.d.ts +102 -102
- package/dist/v2/model/block_meta.d.ts +20 -20
- package/dist/v2/model/content_conversion.d.ts +2 -2
- package/dist/v2/registry/registry.d.ts +1 -1
- package/dist/v2/source_package.d.ts +1 -1
- package/package.json +31 -29
- package/src/cmd/build-meta.ts +15 -15
- package/src/cmd/build-model.ts +23 -26
- package/src/cmd/index.ts +20 -20
- package/src/cmd/list-overview-snapshots.ts +12 -12
- package/src/cmd/mark-stable.ts +30 -33
- package/src/cmd/pack.ts +15 -15
- package/src/cmd/publish.ts +46 -34
- package/src/cmd/refresh-registry.ts +15 -15
- package/src/cmd/restore-overview-from-snapshot.ts +27 -25
- package/src/cmd/update-deps.ts +8 -8
- package/src/cmd/upload-package-v1.ts +33 -33
- package/src/common_types.ts +1 -1
- package/src/io/folder_reader.test.ts +13 -13
- package/src/io/folder_reader.ts +18 -20
- package/src/io/index.ts +2 -2
- package/src/io/storage.test.ts +48 -48
- package/src/io/storage.ts +20 -15
- package/src/lib.ts +3 -3
- package/src/registry_v1/config.ts +11 -11
- package/src/registry_v1/config_schema.ts +5 -5
- package/src/registry_v1/flags.ts +4 -4
- package/src/registry_v1/index.ts +3 -3
- package/src/registry_v1/registry.test.ts +54 -54
- package/src/registry_v1/registry.ts +29 -25
- package/src/registry_v1/v1_repo_schema.ts +3 -3
- package/src/util.ts +6 -9
- package/src/v2/build_dist.test.ts +8 -9
- package/src/v2/build_dist.ts +10 -13
- package/src/v2/index.ts +4 -4
- package/src/v2/model/block_components.ts +5 -5
- package/src/v2/model/block_description.ts +12 -8
- package/src/v2/model/block_meta.ts +4 -5
- package/src/v2/model/content_conversion.ts +44 -44
- package/src/v2/model/index.ts +4 -4
- package/src/v2/registry/index.ts +3 -3
- package/src/v2/registry/registry.test.ts +223 -197
- package/src/v2/registry/registry.ts +93 -66
- package/src/v2/registry/registry_reader.test.ts +15 -15
- package/src/v2/registry/registry_reader.ts +29 -27
- package/src/v2/registry/schema_internal.ts +11 -10
- package/src/v2/registry/schema_public.ts +56 -47
- package/src/v2/source_package.test.ts +15 -15
- package/src/v2/source_package.ts +33 -26
- package/dist/config-DKBY0B2u.mjs.map +0 -1
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import type { RegistryStorage } from
|
|
2
|
-
import { randomUUID } from
|
|
3
|
-
import * as semver from
|
|
1
|
+
import type { RegistryStorage } from "../io/storage";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import * as semver from "semver";
|
|
4
4
|
import type {
|
|
5
5
|
BlockPackageNameWithoutVersion,
|
|
6
6
|
FullBlockPackageName,
|
|
7
7
|
GlobalOverview,
|
|
8
|
-
PackageOverview
|
|
8
|
+
PackageOverview,
|
|
9
|
+
} from "./v1_repo_schema";
|
|
9
10
|
import {
|
|
10
11
|
GlobalOverviewPath,
|
|
11
12
|
MetaFile,
|
|
12
13
|
packageOverviewPath,
|
|
13
14
|
payloadFilePath,
|
|
14
|
-
} from
|
|
15
|
-
import type { MiLogger } from
|
|
15
|
+
} from "./v1_repo_schema";
|
|
16
|
+
import type { MiLogger } from "@milaboratories/ts-helpers";
|
|
16
17
|
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18
19
|
function fullNameToPath(name: FullBlockPackageName): string {
|
|
19
20
|
return `${name.organization}/${name.package}/${name.version}`;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
const VersionUpdatesPrefix =
|
|
23
|
+
const VersionUpdatesPrefix = "_updates_v1/per_package_version/";
|
|
23
24
|
|
|
24
25
|
function packageUpdatePath(bp: FullBlockPackageName, seed: string): string {
|
|
25
26
|
return `${VersionUpdatesPrefix}${bp.organization}/${bp.package}/${bp.version}/${seed}`;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const PackageUpdatePattern
|
|
29
|
-
|
|
29
|
+
const PackageUpdatePattern =
|
|
30
|
+
/(?<packageKeyWithoutVersion>(?<organization>[^/]+)\/(?<pkg>[^/]+))\/(?<version>[^/]+)\/(?<seed>[^/]+)$/;
|
|
30
31
|
|
|
31
|
-
const GlobalUpdateSeedInFile =
|
|
32
|
-
const GlobalUpdateSeedOutFile =
|
|
32
|
+
const GlobalUpdateSeedInFile = "_updates_v1/_global_update_in";
|
|
33
|
+
const GlobalUpdateSeedOutFile = "_updates_v1/_global_update_out";
|
|
33
34
|
|
|
34
35
|
/*
|
|
35
36
|
Note on convergence guarantee.
|
|
@@ -87,13 +88,13 @@ export class BlockRegistry {
|
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
private async updateRegistry(): Promise<void> {
|
|
90
|
-
this.logger?.info(
|
|
91
|
+
this.logger?.info("Initiating registry refresh...");
|
|
91
92
|
|
|
92
93
|
// reading update requests
|
|
93
94
|
const packagesToUpdate = new Map<string, PackageUpdateInfo>();
|
|
94
95
|
const seedPaths: string[] = [];
|
|
95
96
|
const rawSeedPaths = await this.storage.listFiles(VersionUpdatesPrefix);
|
|
96
|
-
this.logger?.info(
|
|
97
|
+
this.logger?.info("Packages to be updated:");
|
|
97
98
|
for (const seedPath of rawSeedPaths) {
|
|
98
99
|
const match = seedPath.match(PackageUpdatePattern);
|
|
99
100
|
if (!match) continue;
|
|
@@ -114,8 +115,8 @@ export class BlockRegistry {
|
|
|
114
115
|
|
|
115
116
|
// loading global overview
|
|
116
117
|
const overviewContent = await this.storage.getFile(GlobalOverviewPath);
|
|
117
|
-
let overview: GlobalOverview
|
|
118
|
-
|
|
118
|
+
let overview: GlobalOverview =
|
|
119
|
+
overviewContent === undefined
|
|
119
120
|
? []
|
|
120
121
|
: (JSON.parse(overviewContent.toString()) as GlobalOverview);
|
|
121
122
|
this.logger?.info(`Global overview loaded, ${overview.length} records`);
|
|
@@ -125,8 +126,8 @@ export class BlockRegistry {
|
|
|
125
126
|
// reading existing overview
|
|
126
127
|
const overviewFile = packageOverviewPath(packageInfo.package);
|
|
127
128
|
const pOverviewContent = await this.storage.getFile(overviewFile);
|
|
128
|
-
let packageOverview
|
|
129
|
-
|
|
129
|
+
let packageOverview =
|
|
130
|
+
pOverviewContent === undefined
|
|
130
131
|
? []
|
|
131
132
|
: (JSON.parse(pOverviewContent.toString()) as PackageOverview);
|
|
132
133
|
this.logger?.info(
|
|
@@ -149,7 +150,10 @@ export class BlockRegistry {
|
|
|
149
150
|
),
|
|
150
151
|
);
|
|
151
152
|
if (!metaContent) continue;
|
|
152
|
-
packageOverview.push({
|
|
153
|
+
packageOverview.push({
|
|
154
|
+
version,
|
|
155
|
+
meta: JSON.parse(metaContent.toString()) as Record<string, unknown>,
|
|
156
|
+
});
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
// sorting entries according to version
|
|
@@ -162,8 +166,8 @@ export class BlockRegistry {
|
|
|
162
166
|
// patching corresponding entry in overview
|
|
163
167
|
overview = overview.filter(
|
|
164
168
|
(e) =>
|
|
165
|
-
e.organization !== packageInfo.package.organization
|
|
166
|
-
|
|
169
|
+
e.organization !== packageInfo.package.organization ||
|
|
170
|
+
e.package !== packageInfo.package.package,
|
|
167
171
|
);
|
|
168
172
|
overview.push({
|
|
169
173
|
organization: packageInfo.package.organization,
|
|
@@ -191,10 +195,10 @@ export class BlockRegistry {
|
|
|
191
195
|
const currentUpdatedSeed = await this.storage.getFile(GlobalUpdateSeedOutFile);
|
|
192
196
|
if (!force && updateRequestSeed === undefined && currentUpdatedSeed === undefined) return;
|
|
193
197
|
if (
|
|
194
|
-
!force
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
!force &&
|
|
199
|
+
updateRequestSeed !== undefined &&
|
|
200
|
+
currentUpdatedSeed !== undefined &&
|
|
201
|
+
updateRequestSeed.equals(currentUpdatedSeed)
|
|
198
202
|
)
|
|
199
203
|
return;
|
|
200
204
|
|
|
@@ -240,7 +244,7 @@ export class BlockRegistryPackConstructor {
|
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
async finish() {
|
|
243
|
-
if (!this.metaAdded) throw new Error(
|
|
247
|
+
if (!this.metaAdded) throw new Error("meta not added");
|
|
244
248
|
await this.storage.putFile(packageUpdatePath(this.name, this.seed), Buffer.of(0));
|
|
245
249
|
await this.storage.putFile(GlobalUpdateSeedInFile, Buffer.from(this.seed));
|
|
246
250
|
}
|
|
@@ -4,7 +4,7 @@ export interface FullBlockPackageName {
|
|
|
4
4
|
version: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
const MainPrefix =
|
|
7
|
+
const MainPrefix = "v1/";
|
|
8
8
|
|
|
9
9
|
export function packageContentPrefix(bp: FullBlockPackageName): string {
|
|
10
10
|
return `${MainPrefix}${bp.organization}/${bp.package}/${bp.version}`;
|
|
@@ -14,7 +14,7 @@ export function payloadFilePath(bp: FullBlockPackageName, file: string): string
|
|
|
14
14
|
return `${MainPrefix}${bp.organization}/${bp.package}/${bp.version}/${file}`;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export type BlockPackageNameWithoutVersion = Pick<FullBlockPackageName,
|
|
17
|
+
export type BlockPackageNameWithoutVersion = Pick<FullBlockPackageName, "organization" | "package">;
|
|
18
18
|
|
|
19
19
|
export function packageOverviewPath(bp: BlockPackageNameWithoutVersion): string {
|
|
20
20
|
return `${MainPrefix}${bp.organization}/${bp.package}/overview.json`;
|
|
@@ -22,7 +22,7 @@ export function packageOverviewPath(bp: BlockPackageNameWithoutVersion): string
|
|
|
22
22
|
|
|
23
23
|
export const GlobalOverviewPath = `${MainPrefix}overview.json`;
|
|
24
24
|
|
|
25
|
-
export const MetaFile =
|
|
25
|
+
export const MetaFile = "meta.json";
|
|
26
26
|
|
|
27
27
|
export interface PackageOverviewEntry {
|
|
28
28
|
version: string;
|
package/src/util.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BigIntStats } from
|
|
2
|
-
import fsp from
|
|
3
|
-
import { createHash } from
|
|
1
|
+
import type { BigIntStats } from "node:fs";
|
|
2
|
+
import fsp from "node:fs/promises";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
4
|
|
|
5
5
|
export async function tryLoadFile<T>(
|
|
6
6
|
file: string,
|
|
@@ -9,7 +9,7 @@ export async function tryLoadFile<T>(
|
|
|
9
9
|
try {
|
|
10
10
|
return map(await fsp.readFile(file));
|
|
11
11
|
} catch (err: unknown) {
|
|
12
|
-
if (err instanceof Error &&
|
|
12
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") return undefined;
|
|
13
13
|
else throw err;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -18,7 +18,7 @@ export async function tryStat(path: string): Promise<BigIntStats | undefined> {
|
|
|
18
18
|
try {
|
|
19
19
|
return await fsp.stat(path, { bigint: true });
|
|
20
20
|
} catch (error: unknown) {
|
|
21
|
-
if (error instanceof Error &&
|
|
21
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
22
22
|
return undefined;
|
|
23
23
|
}
|
|
24
24
|
throw error;
|
|
@@ -27,9 +27,6 @@ export async function tryStat(path: string): Promise<BigIntStats | undefined> {
|
|
|
27
27
|
|
|
28
28
|
export function calculateSha256(bytes: ArrayBuffer): Promise<string> {
|
|
29
29
|
return Promise.resolve(
|
|
30
|
-
createHash(
|
|
31
|
-
.update(Buffer.from(bytes))
|
|
32
|
-
.digest('hex')
|
|
33
|
-
.toUpperCase(),
|
|
30
|
+
createHash("sha256").update(Buffer.from(bytes)).digest("hex").toUpperCase(),
|
|
34
31
|
);
|
|
35
32
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { randomUUID } from
|
|
2
|
-
import { test
|
|
3
|
-
import { loadPackDescription } from
|
|
4
|
-
import path from
|
|
5
|
-
import
|
|
6
|
-
import { buildBlockPackDist } from './build_dist';
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { loadPackDescription } from "./source_package";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { buildBlockPackDist } from "./build_dist";
|
|
7
6
|
|
|
8
|
-
test.skip(
|
|
7
|
+
test.skip("create dist test", async () => {
|
|
9
8
|
const description = await loadPackDescription(
|
|
10
|
-
|
|
9
|
+
"/Volumes/Data/Projects/MiLaboratory/blocks-beta/block-template",
|
|
11
10
|
);
|
|
12
11
|
console.dir(description, { depth: 5 });
|
|
13
12
|
const uuid = randomUUID();
|
|
14
|
-
const distPath = path.resolve(
|
|
13
|
+
const distPath = path.resolve("tmp", uuid);
|
|
15
14
|
const manifest = await buildBlockPackDist(description, distPath);
|
|
16
15
|
console.dir(manifest, { depth: 5 });
|
|
17
16
|
});
|
package/src/v2/build_dist.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BlockPackDescriptionManifest,
|
|
3
3
|
ManifestFileInfo,
|
|
4
|
-
} from
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import fsp from 'node:fs/promises';
|
|
12
|
-
import path from 'node:path';
|
|
13
|
-
import { calculateSha256 } from '../util';
|
|
4
|
+
} from "@milaboratories/pl-model-middle-layer";
|
|
5
|
+
import { BlockPackManifest, BlockPackManifestFile } from "@milaboratories/pl-model-middle-layer";
|
|
6
|
+
import type { BlockPackDescriptionAbsolute } from "./model";
|
|
7
|
+
import { BlockPackDescriptionConsolidateToFolder } from "./model";
|
|
8
|
+
import fsp from "node:fs/promises";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { calculateSha256 } from "../util";
|
|
14
11
|
|
|
15
12
|
export async function buildBlockPackDist(
|
|
16
13
|
description: BlockPackDescriptionAbsolute,
|
|
@@ -18,8 +15,8 @@ export async function buildBlockPackDist(
|
|
|
18
15
|
): Promise<BlockPackManifest> {
|
|
19
16
|
await fsp.mkdir(dst, { recursive: true });
|
|
20
17
|
const files: string[] = [];
|
|
21
|
-
const descriptionRelative: BlockPackDescriptionManifest
|
|
22
|
-
|
|
18
|
+
const descriptionRelative: BlockPackDescriptionManifest =
|
|
19
|
+
await BlockPackDescriptionConsolidateToFolder(dst, files).parseAsync(description);
|
|
23
20
|
const filesForManifest = await Promise.all(
|
|
24
21
|
files.map(async (f): Promise<ManifestFileInfo> => {
|
|
25
22
|
const bytes = await fsp.readFile(path.resolve(dst, f));
|
|
@@ -29,7 +26,7 @@ export async function buildBlockPackDist(
|
|
|
29
26
|
);
|
|
30
27
|
|
|
31
28
|
const manifest: BlockPackManifest = BlockPackManifest.parse({
|
|
32
|
-
schema:
|
|
29
|
+
schema: "v2",
|
|
33
30
|
description: {
|
|
34
31
|
...descriptionRelative,
|
|
35
32
|
},
|
package/src/v2/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./model";
|
|
2
|
+
export * from "./build_dist";
|
|
3
|
+
export * from "./source_package";
|
|
4
|
+
export * from "./registry";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { z } from
|
|
1
|
+
import type { z } from "zod";
|
|
2
2
|
import {
|
|
3
3
|
ResolvedModuleFile,
|
|
4
4
|
ResolvedModuleFolder,
|
|
5
5
|
packFolderToRelativeTgz,
|
|
6
6
|
cpAbsoluteToRelative,
|
|
7
|
-
} from
|
|
7
|
+
} from "./content_conversion";
|
|
8
8
|
import {
|
|
9
9
|
BlockComponents,
|
|
10
10
|
BlockComponentsManifest,
|
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
ContentAbsoluteFolder,
|
|
13
13
|
ContentRelative,
|
|
14
14
|
mapRemoteToAbsolute,
|
|
15
|
-
} from
|
|
15
|
+
} from "@milaboratories/pl-model-middle-layer";
|
|
16
16
|
|
|
17
17
|
export function BlockComponentsDescription(moduleRoot: string) {
|
|
18
18
|
return BlockComponents(
|
|
19
19
|
ResolvedModuleFile(moduleRoot),
|
|
20
|
-
ResolvedModuleFolder(moduleRoot,
|
|
20
|
+
ResolvedModuleFolder(moduleRoot, "index.html"),
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
export type BlockComponentsDescription = z.infer<ReturnType<typeof BlockComponentsDescription>>;
|
|
@@ -25,7 +25,7 @@ export type BlockComponentsDescription = z.infer<ReturnType<typeof BlockComponen
|
|
|
25
25
|
export function BlockComponentsConsolidate(dstFolder: string, fileAccumulator?: string[]) {
|
|
26
26
|
return BlockComponents(
|
|
27
27
|
ContentAbsoluteBinaryLocal.transform(cpAbsoluteToRelative(dstFolder, fileAccumulator)),
|
|
28
|
-
ContentAbsoluteFolder.transform(packFolderToRelativeTgz(dstFolder,
|
|
28
|
+
ContentAbsoluteFolder.transform(packFolderToRelativeTgz(dstFolder, "ui.tgz", fileAccumulator)),
|
|
29
29
|
).pipe(BlockComponentsManifest);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -7,20 +7,24 @@ import {
|
|
|
7
7
|
ContentRelativeBinary,
|
|
8
8
|
ContentRelativeText,
|
|
9
9
|
CreateBlockPackDescriptionSchema,
|
|
10
|
-
} from
|
|
11
|
-
import { BlockComponentsConsolidate, BlockComponentsDescription } from
|
|
12
|
-
import { BlockPackMetaConsolidate, BlockPackMetaDescription } from
|
|
13
|
-
import type { z } from
|
|
14
|
-
import fsp from
|
|
15
|
-
import type { BlockConfigContainer } from
|
|
16
|
-
import { extractConfigGeneric } from
|
|
10
|
+
} from "@milaboratories/pl-model-middle-layer";
|
|
11
|
+
import { BlockComponentsConsolidate, BlockComponentsDescription } from "./block_components";
|
|
12
|
+
import { BlockPackMetaConsolidate, BlockPackMetaDescription } from "./block_meta";
|
|
13
|
+
import type { z } from "zod";
|
|
14
|
+
import fsp from "node:fs/promises";
|
|
15
|
+
import type { BlockConfigContainer } from "@milaboratories/pl-model-common";
|
|
16
|
+
import { extractConfigGeneric } from "@milaboratories/pl-model-common";
|
|
17
17
|
|
|
18
18
|
export function ResolvedBlockPackDescriptionFromPackageJson(root: string) {
|
|
19
19
|
return CreateBlockPackDescriptionSchema(
|
|
20
20
|
BlockComponentsDescription(root),
|
|
21
21
|
BlockPackMetaDescription(root),
|
|
22
22
|
).transform(async (description, _ctx) => {
|
|
23
|
-
const cfg = extractConfigGeneric(
|
|
23
|
+
const cfg = extractConfigGeneric(
|
|
24
|
+
JSON.parse(
|
|
25
|
+
await fsp.readFile(description.components.model.file, "utf-8"),
|
|
26
|
+
) as BlockConfigContainer,
|
|
27
|
+
);
|
|
24
28
|
const featureFlags = cfg.featureFlags;
|
|
25
29
|
return {
|
|
26
30
|
...description,
|
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
ContentRelativeText,
|
|
9
9
|
DescriptionContentBinary,
|
|
10
10
|
DescriptionContentText,
|
|
11
|
-
} from
|
|
12
|
-
import type {
|
|
13
|
-
RelativeContentReader } from './content_conversion';
|
|
11
|
+
} from "@milaboratories/pl-model-middle-layer";
|
|
12
|
+
import type { RelativeContentReader } from "./content_conversion";
|
|
14
13
|
import {
|
|
15
14
|
absoluteToBase64,
|
|
16
15
|
absoluteToBytes,
|
|
@@ -19,8 +18,8 @@ import {
|
|
|
19
18
|
mapLocalToAbsolute,
|
|
20
19
|
relativeToContentString,
|
|
21
20
|
relativeToExplicitBytes,
|
|
22
|
-
} from
|
|
23
|
-
import type { z } from
|
|
21
|
+
} from "./content_conversion";
|
|
22
|
+
import type { z } from "zod";
|
|
24
23
|
|
|
25
24
|
export function BlockPackMetaDescription(root: string) {
|
|
26
25
|
return BlockPackMeta(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import path from
|
|
3
|
-
import fsp from
|
|
4
|
-
import * as mime from
|
|
5
|
-
import * as tar from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
|
+
import * as mime from "mime-types";
|
|
5
|
+
import * as tar from "tar";
|
|
6
6
|
import type {
|
|
7
7
|
ContentAbsoluteBinaryLocal,
|
|
8
8
|
ContentAbsoluteFile,
|
|
@@ -15,17 +15,17 @@ import type {
|
|
|
15
15
|
ContentRelative,
|
|
16
16
|
ContentRelativeBinary,
|
|
17
17
|
ContentRelativeText,
|
|
18
|
-
} from
|
|
19
|
-
import { tryResolve } from
|
|
18
|
+
} from "@milaboratories/pl-model-middle-layer";
|
|
19
|
+
import { tryResolve } from "@milaboratories/resolve-helper";
|
|
20
20
|
|
|
21
21
|
type ContentCtxFs = {
|
|
22
|
-
type:
|
|
22
|
+
type: "local";
|
|
23
23
|
/** Folder relative to which content should be resolved */
|
|
24
24
|
path: string;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
type ContentCtxUrl = {
|
|
28
|
-
type:
|
|
28
|
+
type: "remote";
|
|
29
29
|
/** URL prefix from which content should be resolved */
|
|
30
30
|
url: string;
|
|
31
31
|
};
|
|
@@ -52,7 +52,7 @@ export function ResolvedModuleFile(moduleRoot: string) {
|
|
|
52
52
|
return z.NEVER;
|
|
53
53
|
}
|
|
54
54
|
return {
|
|
55
|
-
type:
|
|
55
|
+
type: "absolute-file",
|
|
56
56
|
file: result,
|
|
57
57
|
};
|
|
58
58
|
});
|
|
@@ -67,7 +67,7 @@ export function ResolvedModuleFolder(
|
|
|
67
67
|
...indexFilesToLookFor: [string, ...string[]]
|
|
68
68
|
) {
|
|
69
69
|
return z.string().transform<ContentAbsoluteFolder>((request, ctx) => {
|
|
70
|
-
const requestWithSlash = request.endsWith(
|
|
70
|
+
const requestWithSlash = request.endsWith("/") ? request : `${request}/`;
|
|
71
71
|
|
|
72
72
|
for (const idxFile of indexFilesToLookFor) {
|
|
73
73
|
const result = tryResolve(moduleRoot, requestWithSlash + idxFile);
|
|
@@ -75,7 +75,7 @@ export function ResolvedModuleFolder(
|
|
|
75
75
|
if (!result.endsWith(idxFile))
|
|
76
76
|
throw new Error(`Unexpected resolve result ${result} with index file ${idxFile}`);
|
|
77
77
|
return {
|
|
78
|
-
type:
|
|
78
|
+
type: "absolute-folder",
|
|
79
79
|
folder: result.slice(0, result.length - idxFile.length),
|
|
80
80
|
};
|
|
81
81
|
}
|
|
@@ -83,7 +83,7 @@ export function ResolvedModuleFolder(
|
|
|
83
83
|
|
|
84
84
|
ctx.addIssue({
|
|
85
85
|
code: z.ZodIssueCode.custom,
|
|
86
|
-
message: `Can't resolve ${request} folder against ${moduleRoot}, no index file found (${indexFilesToLookFor.join(
|
|
86
|
+
message: `Can't resolve ${request} folder against ${moduleRoot}, no index file found (${indexFilesToLookFor.join(", ")})`,
|
|
87
87
|
});
|
|
88
88
|
return z.NEVER;
|
|
89
89
|
});
|
|
@@ -93,53 +93,53 @@ export function mapLocalToAbsolute(
|
|
|
93
93
|
root: string,
|
|
94
94
|
): <T extends ContentAnyLocal>(value: T) => Exclude<T, ContentRelative> | ContentAbsoluteFile {
|
|
95
95
|
return <T extends ContentAnyLocal>(value: T) =>
|
|
96
|
-
value.type ===
|
|
97
|
-
? { type:
|
|
96
|
+
value.type === "relative"
|
|
97
|
+
? { type: "absolute-file", file: path.resolve(root, value.path) }
|
|
98
98
|
: (value as Exclude<T, ContentRelative>);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
export function absoluteToString(): (value: ContentAbsoluteTextLocal) => Promise<string> {
|
|
102
102
|
return async (value) => {
|
|
103
|
-
if (value.type ===
|
|
104
|
-
return await fsp.readFile(value.file, { encoding:
|
|
103
|
+
if (value.type === "absolute-file")
|
|
104
|
+
return await fsp.readFile(value.file, { encoding: "utf-8" });
|
|
105
105
|
else return value.content;
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// TODO add type and size limitations
|
|
110
110
|
export function absoluteToBase64(): (
|
|
111
|
-
value: ContentAbsoluteBinaryLocal
|
|
111
|
+
value: ContentAbsoluteBinaryLocal,
|
|
112
112
|
) => Promise<ContentExplicitBase64> {
|
|
113
113
|
return async (value) => {
|
|
114
|
-
if (value.type ===
|
|
114
|
+
if (value.type === "absolute-file") {
|
|
115
115
|
const mimeType = mime.lookup(value.file);
|
|
116
116
|
if (!mimeType) throw new Error(`Can't recognize mime type of the file: ${value.file}.`);
|
|
117
117
|
return {
|
|
118
|
-
type:
|
|
118
|
+
type: "explicit-base64",
|
|
119
119
|
mimeType,
|
|
120
|
-
content: await fsp.readFile(value.file, { encoding:
|
|
120
|
+
content: await fsp.readFile(value.file, { encoding: "base64" }),
|
|
121
121
|
};
|
|
122
122
|
} else return value;
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
export function absoluteToBytes(): (
|
|
127
|
-
value: ContentAbsoluteBinaryLocal
|
|
127
|
+
value: ContentAbsoluteBinaryLocal,
|
|
128
128
|
) => Promise<ContentExplicitBytes> {
|
|
129
129
|
return async (value) => {
|
|
130
|
-
if (value.type ===
|
|
130
|
+
if (value.type === "absolute-file") {
|
|
131
131
|
const mimeType = mime.lookup(value.file);
|
|
132
132
|
if (!mimeType) throw new Error(`Can't recognize mime type of the file: ${value.file}.`);
|
|
133
133
|
return {
|
|
134
|
-
type:
|
|
134
|
+
type: "explicit-bytes",
|
|
135
135
|
mimeType,
|
|
136
136
|
content: Buffer.from(await fsp.readFile(value.file)),
|
|
137
137
|
};
|
|
138
|
-
} else if (value.type ===
|
|
138
|
+
} else if (value.type === "explicit-base64") {
|
|
139
139
|
return {
|
|
140
|
-
type:
|
|
140
|
+
type: "explicit-bytes",
|
|
141
141
|
mimeType: value.mimeType,
|
|
142
|
-
content: Buffer.from(value.content,
|
|
142
|
+
content: Buffer.from(value.content, "base64"),
|
|
143
143
|
};
|
|
144
144
|
} else return value;
|
|
145
145
|
};
|
|
@@ -149,16 +149,16 @@ export function cpAbsoluteToRelative(
|
|
|
149
149
|
dstFolder: string,
|
|
150
150
|
fileAccumulator?: string[],
|
|
151
151
|
): <T extends Exclude<ContentAnyLocal, ContentRelative>>(
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
value: T,
|
|
153
|
+
) => Promise<Exclude<T, ContentAbsoluteFile> | ContentRelative> {
|
|
154
154
|
return async <T extends Exclude<ContentAnyLocal, ContentRelative>>(value: T) => {
|
|
155
|
-
if (value.type ===
|
|
155
|
+
if (value.type === "absolute-file") {
|
|
156
156
|
const fileName = path.basename(value.file);
|
|
157
157
|
const dst = path.resolve(dstFolder, fileName);
|
|
158
158
|
fileAccumulator?.push(fileName);
|
|
159
159
|
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
160
160
|
await fsp.cp(value.file, dst);
|
|
161
|
-
return { type:
|
|
161
|
+
return { type: "relative", path: fileName };
|
|
162
162
|
} else return value as Exclude<T, ContentAbsoluteFile>;
|
|
163
163
|
};
|
|
164
164
|
}
|
|
@@ -168,7 +168,7 @@ export function packFolderToRelativeTgz(
|
|
|
168
168
|
tgzName: string,
|
|
169
169
|
fileAccumulator?: string[],
|
|
170
170
|
): (value: ContentAbsoluteFolder) => Promise<ContentRelative> {
|
|
171
|
-
if (!tgzName.endsWith(
|
|
171
|
+
if (!tgzName.endsWith(".tgz")) throw new Error(`Unexpected tgz file name: ${tgzName}`);
|
|
172
172
|
return async (value: ContentAbsoluteFolder) => {
|
|
173
173
|
const dst = path.resolve(dstFolder, tgzName);
|
|
174
174
|
await tar.create(
|
|
@@ -177,10 +177,10 @@ export function packFolderToRelativeTgz(
|
|
|
177
177
|
file: dst,
|
|
178
178
|
cwd: value.folder,
|
|
179
179
|
},
|
|
180
|
-
[
|
|
180
|
+
["."],
|
|
181
181
|
);
|
|
182
182
|
fileAccumulator?.push(tgzName);
|
|
183
|
-
return { type:
|
|
183
|
+
return { type: "relative", path: tgzName };
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -190,29 +190,29 @@ export function relativeToExplicitString(
|
|
|
190
190
|
reader: RelativeContentReader,
|
|
191
191
|
): (value: ContentRelativeText) => Promise<ContentExplicitString> {
|
|
192
192
|
return async (value) =>
|
|
193
|
-
value.type ===
|
|
193
|
+
value.type === "explicit-string"
|
|
194
194
|
? value
|
|
195
|
-
: { type:
|
|
195
|
+
: { type: "explicit-string", content: (await reader(value.path)).toString("utf8") };
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
export function relativeToContentString(
|
|
199
199
|
reader: RelativeContentReader,
|
|
200
200
|
): (value: ContentRelativeText) => Promise<string> {
|
|
201
201
|
return async (value) =>
|
|
202
|
-
value.type ===
|
|
202
|
+
value.type === "explicit-string" ? value.content : (await reader(value.path)).toString("utf8");
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
export function relativeToExplicitBinary64(
|
|
206
206
|
reader: RelativeContentReader,
|
|
207
207
|
): (value: ContentRelativeBinary) => Promise<ContentExplicitBase64> {
|
|
208
208
|
return async (value) => {
|
|
209
|
-
if (value.type ===
|
|
209
|
+
if (value.type === "explicit-base64") return value;
|
|
210
210
|
const mimeType = mime.lookup(value.path);
|
|
211
211
|
if (!mimeType) throw new Error(`Can't recognize mime type of the file: ${value.path}.`);
|
|
212
212
|
return {
|
|
213
|
-
type:
|
|
213
|
+
type: "explicit-base64",
|
|
214
214
|
mimeType,
|
|
215
|
-
content: (await reader(value.path)).toString(
|
|
215
|
+
content: (await reader(value.path)).toString("base64"),
|
|
216
216
|
};
|
|
217
217
|
};
|
|
218
218
|
}
|
|
@@ -221,16 +221,16 @@ export function relativeToExplicitBytes(
|
|
|
221
221
|
reader: RelativeContentReader,
|
|
222
222
|
): (value: ContentRelativeBinary) => Promise<ContentExplicitBytes> {
|
|
223
223
|
return async (value) => {
|
|
224
|
-
if (value.type ===
|
|
224
|
+
if (value.type === "explicit-base64")
|
|
225
225
|
return {
|
|
226
|
-
type:
|
|
226
|
+
type: "explicit-bytes",
|
|
227
227
|
mimeType: value.mimeType,
|
|
228
|
-
content: Buffer.from(value.content,
|
|
228
|
+
content: Buffer.from(value.content, "base64"),
|
|
229
229
|
};
|
|
230
230
|
const mimeType = mime.lookup(value.path);
|
|
231
231
|
if (!mimeType) throw new Error(`Can't recognize mime type of the file: ${value.path}.`);
|
|
232
232
|
return {
|
|
233
|
-
type:
|
|
233
|
+
type: "explicit-bytes",
|
|
234
234
|
mimeType,
|
|
235
235
|
content: await reader(value.path),
|
|
236
236
|
};
|
package/src/v2/model/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./content_conversion";
|
|
2
2
|
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
3
|
+
export * from "./block_meta";
|
|
4
|
+
export * from "./block_components";
|
|
5
|
+
export * from "./block_description";
|
package/src/v2/registry/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./registry";
|
|
2
|
+
export * from "./registry_reader";
|
|
3
|
+
export * from "./schema_public";
|