@antelopejs/dms 0.9.0 → 0.9.1
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/CHANGELOG.md +16 -0
- package/data/module-store/catalog.json +71 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/implementations/dms/frontend-modules.d.ts +2 -0
- package/dist/implementations/dms/frontend-modules.js +29 -1
- package/dist/implementations/dms/frontend-modules.js.map +1 -1
- package/dist/implementations/dms/frontend-ready.d.ts +8 -0
- package/dist/implementations/dms/frontend-ready.js +34 -0
- package/dist/implementations/dms/frontend-ready.js.map +1 -0
- package/dist/implementations/dms/manifest.d.ts +1 -0
- package/dist/implementations/dms/manifest.js.map +1 -1
- package/dist/implementations/dms/page.d.ts +2 -0
- package/dist/implementations/dms/page.js +16 -0
- package/dist/implementations/dms/page.js.map +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/store.d.ts +21 -0
- package/dist/routes/store.js +130 -0
- package/dist/routes/store.js.map +1 -0
- package/dist/store/activity.d.ts +2 -0
- package/dist/store/activity.js +12 -0
- package/dist/store/activity.js.map +1 -0
- package/dist/store/cache.d.ts +8 -0
- package/dist/store/cache.js +29 -0
- package/dist/store/cache.js.map +1 -0
- package/dist/store/catalog.d.ts +4 -0
- package/dist/store/catalog.js +69 -0
- package/dist/store/catalog.js.map +1 -0
- package/dist/store/compatibility.d.ts +3 -0
- package/dist/store/compatibility.js +45 -0
- package/dist/store/compatibility.js.map +1 -0
- package/dist/store/declarations.d.ts +18 -0
- package/dist/store/declarations.js +116 -0
- package/dist/store/declarations.js.map +1 -0
- package/dist/store/frontend-compatibility.d.ts +18 -0
- package/dist/store/frontend-compatibility.js +93 -0
- package/dist/store/frontend-compatibility.js.map +1 -0
- package/dist/store/interfaces.d.ts +6 -0
- package/dist/store/interfaces.js +126 -0
- package/dist/store/interfaces.js.map +1 -0
- package/dist/store/listing.d.ts +2 -0
- package/dist/store/listing.js +180 -0
- package/dist/store/listing.js.map +1 -0
- package/dist/store/operations.d.ts +8 -0
- package/dist/store/operations.js +254 -0
- package/dist/store/operations.js.map +1 -0
- package/dist/store/registry.d.ts +4 -0
- package/dist/store/registry.js +61 -0
- package/dist/store/registry.js.map +1 -0
- package/dist/store/requirements.d.ts +14 -0
- package/dist/store/requirements.js +81 -0
- package/dist/store/requirements.js.map +1 -0
- package/dist/store/runtime.d.ts +11 -0
- package/dist/store/runtime.js +78 -0
- package/dist/store/runtime.js.map +1 -0
- package/dist/store/tarball.d.ts +2 -0
- package/dist/store/tarball.js +80 -0
- package/dist/store/tarball.js.map +1 -0
- package/dist/store/types.d.ts +98 -0
- package/dist/store/types.js +3 -0
- package/dist/store/types.js.map +1 -0
- package/dist/test/unit/store/store.test.d.ts +1 -0
- package/dist/test/unit/store/store.test.js +127 -0
- package/dist/test/unit/store/store.test.js.map +1 -0
- package/dist/validation/store.schema.d.ts +39 -0
- package/dist/validation/store.schema.js +27 -0
- package/dist/validation/store.schema.js.map +1 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreDependencyPicker.vue +136 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreRequirements.vue +98 -0
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleStoreTile.vue +247 -29
- package/frontend-vue/layers/dms-layout/app/build/components/pages/modules/ModuleTile.vue +19 -2
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-catalog.ts +186 -120
- package/frontend-vue/layers/dms-layout/app/build/utils/module-store-install.ts +146 -0
- package/frontend-vue/layers/dms-layout/app/composables/page/useModuleStore.ts +109 -0
- package/frontend-vue/layers/dms-layout/app/custom-pages/modules.vue +335 -34
- package/frontend-vue/layers/dms-layout/app/types/module-store.ts +134 -0
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +107 -9
- package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +107 -9
- package/frontend-vue/package.json +3 -3
- package/frontend-vue/pnpm-lock.yaml +16 -22
- package/frontend-vue/tests/module-store-catalog.test.ts +270 -51
- package/frontend-vue/tests/top-list-card-period-badge-ssr.test.ts +212 -0
- package/package.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.readTarFile = readTarFile;
|
|
7
|
+
exports.readPublishedFiles = readPublishedFiles;
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_os_1 = require("node:os");
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const node_util_1 = require("node:util");
|
|
13
|
+
const node_zlib_1 = require("node:zlib");
|
|
14
|
+
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
15
|
+
const NPM_PACK_TIMEOUT_MS = 60_000;
|
|
16
|
+
const TAR_BLOCK_SIZE = 512;
|
|
17
|
+
const TAR_NAME_LENGTH = 100;
|
|
18
|
+
const TAR_SIZE_OFFSET = 124;
|
|
19
|
+
const TAR_SIZE_LENGTH = 12;
|
|
20
|
+
const TAR_TYPE_OFFSET = 156;
|
|
21
|
+
const TAR_PREFIX_OFFSET = 345;
|
|
22
|
+
const TAR_PREFIX_LENGTH = 155;
|
|
23
|
+
const OCTAL = 8;
|
|
24
|
+
const PACKAGE_ROOT = "package/";
|
|
25
|
+
const TEMP_PREFIX = "dms-store-pack-";
|
|
26
|
+
function readString(block, offset, length) {
|
|
27
|
+
const raw = block.subarray(offset, offset + length);
|
|
28
|
+
const end = raw.indexOf(0);
|
|
29
|
+
return raw.subarray(0, end === -1 ? raw.length : end).toString("utf-8");
|
|
30
|
+
}
|
|
31
|
+
function readHeader(block) {
|
|
32
|
+
const name = readString(block, 0, TAR_NAME_LENGTH);
|
|
33
|
+
if (!name)
|
|
34
|
+
return undefined;
|
|
35
|
+
const prefix = readString(block, TAR_PREFIX_OFFSET, TAR_PREFIX_LENGTH);
|
|
36
|
+
return {
|
|
37
|
+
name: prefix ? `${prefix}/${name}` : name,
|
|
38
|
+
size: Number.parseInt(readString(block, TAR_SIZE_OFFSET, TAR_SIZE_LENGTH).trim(), OCTAL) || 0,
|
|
39
|
+
type: readString(block, TAR_TYPE_OFFSET, 1),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function readTarFile(archive, filePath) {
|
|
43
|
+
const wanted = `${PACKAGE_ROOT}${filePath}`;
|
|
44
|
+
let offset = 0;
|
|
45
|
+
while (offset + TAR_BLOCK_SIZE <= archive.length) {
|
|
46
|
+
const header = readHeader(archive.subarray(offset, offset + TAR_BLOCK_SIZE));
|
|
47
|
+
if (!header)
|
|
48
|
+
return undefined;
|
|
49
|
+
const start = offset + TAR_BLOCK_SIZE;
|
|
50
|
+
if (header.name === wanted) {
|
|
51
|
+
return archive.subarray(start, start + header.size);
|
|
52
|
+
}
|
|
53
|
+
offset = start + Math.ceil(header.size / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
async function packRelease(spec, projectPath, destination) {
|
|
58
|
+
await execFileAsync("npm", ["pack", spec, "--pack-destination", destination, "--silent"], { cwd: projectPath, timeout: NPM_PACK_TIMEOUT_MS });
|
|
59
|
+
const [file] = await (0, promises_1.readdir)(destination);
|
|
60
|
+
if (!file)
|
|
61
|
+
throw new Error(`npm pack ${spec} wrote no archive`);
|
|
62
|
+
return (0, node_zlib_1.gunzipSync)(await (0, promises_1.readFile)(node_path_1.default.join(destination, file)));
|
|
63
|
+
}
|
|
64
|
+
async function readPublishedFiles(packageName, version, projectPath, filePaths) {
|
|
65
|
+
const destination = await (0, promises_1.mkdtemp)(node_path_1.default.join((0, node_os_1.tmpdir)(), TEMP_PREFIX));
|
|
66
|
+
try {
|
|
67
|
+
const archive = await packRelease(`${packageName}@${version}`, projectPath, destination);
|
|
68
|
+
const files = new Map();
|
|
69
|
+
for (const filePath of filePaths) {
|
|
70
|
+
const content = readTarFile(archive, filePath);
|
|
71
|
+
if (content)
|
|
72
|
+
files.set(filePath, content.toString("utf-8"));
|
|
73
|
+
}
|
|
74
|
+
return files;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
await (0, promises_1.rm)(destination, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=tarball.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.js","sourceRoot":"","sources":["../../src/store/tarball.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export interface StoreCatalogEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
package: string;
|
|
4
|
+
icon: string;
|
|
5
|
+
category: string;
|
|
6
|
+
}
|
|
7
|
+
export interface StoreCatalog {
|
|
8
|
+
version: number;
|
|
9
|
+
modules: StoreCatalogEntry[];
|
|
10
|
+
}
|
|
11
|
+
export interface StoreDeclaration {
|
|
12
|
+
key: string;
|
|
13
|
+
package: string;
|
|
14
|
+
range: string;
|
|
15
|
+
disabled: boolean;
|
|
16
|
+
config?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface PackageRelease {
|
|
19
|
+
version: string;
|
|
20
|
+
interfaceRange?: string;
|
|
21
|
+
dependencies?: Record<string, string>;
|
|
22
|
+
implements?: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface RuntimeModule {
|
|
25
|
+
id: string;
|
|
26
|
+
packageName?: string;
|
|
27
|
+
version?: string;
|
|
28
|
+
status: string;
|
|
29
|
+
localPath: string;
|
|
30
|
+
}
|
|
31
|
+
export type StoreOperationKind = "install" | "update" | "enable" | "disable" | "uninstall" | "apply";
|
|
32
|
+
export type StoreOperationStep = "resolve" | "dependencies" | "unload" | "load" | "save";
|
|
33
|
+
export interface StoreOperation {
|
|
34
|
+
moduleId: string;
|
|
35
|
+
kind: StoreOperationKind;
|
|
36
|
+
step: StoreOperationStep;
|
|
37
|
+
targetVersion?: string;
|
|
38
|
+
startedAt: number;
|
|
39
|
+
}
|
|
40
|
+
export type StoreModuleState = "available" | "busy" | "active" | "disabled" | "error" | "pending";
|
|
41
|
+
export type StoreFrontendState = "none" | "synced" | "pending" | "unknown";
|
|
42
|
+
export interface InterfaceImplementation {
|
|
43
|
+
name: string;
|
|
44
|
+
package: string;
|
|
45
|
+
}
|
|
46
|
+
export interface MissingInterface {
|
|
47
|
+
interfacePackage: string;
|
|
48
|
+
candidates: InterfaceImplementation[];
|
|
49
|
+
}
|
|
50
|
+
export interface FrontendBreak {
|
|
51
|
+
name: string;
|
|
52
|
+
range: string;
|
|
53
|
+
}
|
|
54
|
+
export interface FrontendRequirement {
|
|
55
|
+
range: string;
|
|
56
|
+
running: string;
|
|
57
|
+
target?: string;
|
|
58
|
+
command?: string;
|
|
59
|
+
breaks: FrontendBreak[];
|
|
60
|
+
}
|
|
61
|
+
export type FrontendVersionSource = "reported" | "project";
|
|
62
|
+
export interface StoreListingEntry {
|
|
63
|
+
id: string;
|
|
64
|
+
package: string;
|
|
65
|
+
icon: string;
|
|
66
|
+
category: string;
|
|
67
|
+
title: string;
|
|
68
|
+
description: string;
|
|
69
|
+
state: StoreModuleState;
|
|
70
|
+
installedVersion?: string;
|
|
71
|
+
declaredRange?: string;
|
|
72
|
+
latestVersion?: string;
|
|
73
|
+
updateAvailable: boolean;
|
|
74
|
+
compatible: boolean;
|
|
75
|
+
requiredInterfaceRange?: string;
|
|
76
|
+
error?: string;
|
|
77
|
+
operation?: StoreOperation;
|
|
78
|
+
frontend: StoreFrontendState;
|
|
79
|
+
frontendRange?: string;
|
|
80
|
+
frontendRequirement?: FrontendRequirement;
|
|
81
|
+
missingInterfaces: MissingInterface[];
|
|
82
|
+
dependents: string[];
|
|
83
|
+
}
|
|
84
|
+
export interface StoreListing {
|
|
85
|
+
enabled: boolean;
|
|
86
|
+
modules: StoreListingEntry[];
|
|
87
|
+
busy: boolean;
|
|
88
|
+
interfaceVersion: string;
|
|
89
|
+
dev: boolean;
|
|
90
|
+
configError?: string;
|
|
91
|
+
frontendVersion?: string;
|
|
92
|
+
frontendVersionSource?: FrontendVersionSource;
|
|
93
|
+
}
|
|
94
|
+
export interface StoreDependencyChoice {
|
|
95
|
+
interfacePackage: string;
|
|
96
|
+
package: string;
|
|
97
|
+
config?: Record<string, unknown>;
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const config_1 = require("../../../config");
|
|
5
|
+
const catalog_1 = require("../../../store/catalog");
|
|
6
|
+
const compatibility_1 = require("../../../store/compatibility");
|
|
7
|
+
const declarations_1 = require("../../../store/declarations");
|
|
8
|
+
const frontend_compatibility_1 = require("../../../store/frontend-compatibility");
|
|
9
|
+
const runtime_1 = require("../../../store/runtime");
|
|
10
|
+
const tarball_1 = require("../../../store/tarball");
|
|
11
|
+
const store_schema_1 = require("../../../validation/store.schema");
|
|
12
|
+
function runtimeModule(status) {
|
|
13
|
+
return {
|
|
14
|
+
id: "@antelopejs/dms-lang",
|
|
15
|
+
packageName: "@antelopejs/dms-lang",
|
|
16
|
+
status,
|
|
17
|
+
localPath: "/modules/dms-lang",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
describe("[unit] store/catalog", () => {
|
|
21
|
+
it("reads the bundled catalog, one entry per official module", async () => {
|
|
22
|
+
const catalog = await (0, catalog_1.loadStoreCatalog)();
|
|
23
|
+
const ids = catalog.map((entry) => entry.id);
|
|
24
|
+
(0, chai_1.expect)(ids).to.include.members(["lang", "media", "database"]);
|
|
25
|
+
(0, chai_1.expect)(new Set(ids).size).to.equal(ids.length);
|
|
26
|
+
});
|
|
27
|
+
it("drops an entry missing a field rather than half-reading it", () => {
|
|
28
|
+
const entries = (0, catalog_1.readCatalogDocument)({
|
|
29
|
+
version: 1,
|
|
30
|
+
modules: [
|
|
31
|
+
{
|
|
32
|
+
id: "lang",
|
|
33
|
+
package: "@antelopejs/dms-lang",
|
|
34
|
+
icon: "i",
|
|
35
|
+
category: "content",
|
|
36
|
+
},
|
|
37
|
+
{ id: "nameless", icon: "i", category: "content" },
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
(0, chai_1.expect)(entries.map((entry) => entry.id)).to.deep.equal(["lang"]);
|
|
41
|
+
});
|
|
42
|
+
it("refuses a catalog of another version", () => {
|
|
43
|
+
(0, chai_1.expect)(() => (0, catalog_1.readCatalogDocument)({ version: 2, modules: [] })).to.throw(/Unsupported module catalog version/);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("[unit] store/compatibility", () => {
|
|
47
|
+
it("follows the interface range a release depends on", () => {
|
|
48
|
+
const release = { version: "1.0.0", interfaceRange: ">=0.6.0 <1.0.0" };
|
|
49
|
+
(0, chai_1.expect)((0, compatibility_1.isCompatible)(release, "0.6.1")).to.equal(true);
|
|
50
|
+
(0, chai_1.expect)((0, compatibility_1.isCompatible)(release, "0.5.9")).to.equal(false);
|
|
51
|
+
});
|
|
52
|
+
it("does not hold back a release that names no range", () => {
|
|
53
|
+
(0, chai_1.expect)((0, compatibility_1.isCompatible)({ version: "1.0.0" }, "0.6.1")).to.equal(true);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe("[unit] store/runtime", () => {
|
|
57
|
+
it("counts a module as running only while it holds an instance", () => {
|
|
58
|
+
(0, chai_1.expect)((0, runtime_1.isLive)(runtimeModule("active"))).to.equal(true);
|
|
59
|
+
(0, chai_1.expect)((0, runtime_1.isLive)(runtimeModule("constructed"))).to.equal(true);
|
|
60
|
+
(0, chai_1.expect)((0, runtime_1.isLive)(runtimeModule("loaded"))).to.equal(false);
|
|
61
|
+
(0, chai_1.expect)((0, runtime_1.isLive)(undefined)).to.equal(false);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe("[unit] store/declarations", () => {
|
|
65
|
+
it("writes a package source at the given range", () => {
|
|
66
|
+
(0, chai_1.expect)((0, declarations_1.packageDeclarationSource)("@antelopejs/dms-lang", "^0.1.1")).to.deep.equal({
|
|
67
|
+
type: "package",
|
|
68
|
+
package: "@antelopejs/dms-lang",
|
|
69
|
+
version: "^0.1.1",
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe("[unit] store/editable", () => {
|
|
74
|
+
it("follows the runtime mode by default", () => {
|
|
75
|
+
(0, chai_1.expect)((0, config_1.isStoreEditable)(true)).to.equal(true);
|
|
76
|
+
(0, chai_1.expect)((0, config_1.isStoreEditable)(false)).to.equal(false);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
function tarEntry(name, content) {
|
|
80
|
+
const header = Buffer.alloc(512);
|
|
81
|
+
header.write(name, 0);
|
|
82
|
+
header.write(`${content.length.toString(8).padStart(11, "0")}\0`, 124);
|
|
83
|
+
header.write("0", 156);
|
|
84
|
+
const body = Buffer.alloc(Math.ceil(content.length / 512) * 512);
|
|
85
|
+
body.write(content);
|
|
86
|
+
return Buffer.concat([header, body]);
|
|
87
|
+
}
|
|
88
|
+
describe("[unit] store/tarball", () => {
|
|
89
|
+
it("reads one file of an npm archive by its path in the package", () => {
|
|
90
|
+
const archive = Buffer.concat([
|
|
91
|
+
tarEntry("package/package.json", '{"name":"a"}'),
|
|
92
|
+
tarEntry("package/frontend-vue/package.json", '{"engines":{}}'),
|
|
93
|
+
Buffer.alloc(1024),
|
|
94
|
+
]);
|
|
95
|
+
(0, chai_1.expect)((0, tarball_1.readTarFile)(archive, "frontend-vue/package.json")?.toString()).to.equal('{"engines":{}}');
|
|
96
|
+
(0, chai_1.expect)((0, tarball_1.readTarFile)(archive, "missing.json")).to.equal(undefined);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe("[unit] store/frontend-compatibility", () => {
|
|
100
|
+
it("checks a prerelease as the release it leads to", () => {
|
|
101
|
+
(0, chai_1.expect)((0, frontend_compatibility_1.supportsFrontend)(">=0.6.0 <0.7.0", "0.6.0")).to.equal(true);
|
|
102
|
+
(0, chai_1.expect)((0, frontend_compatibility_1.supportsFrontend)(">=0.6.0 <0.7.0", "0.7.0-next.1")).to.equal(false);
|
|
103
|
+
(0, chai_1.expect)((0, frontend_compatibility_1.supportsFrontend)("<0.6.0", "0.6.0")).to.equal(false);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("[unit] validation/store", () => {
|
|
107
|
+
const install = (packageName) => store_schema_1.storeInstallSchema.safeParse({
|
|
108
|
+
id: "lang",
|
|
109
|
+
dependencies: [
|
|
110
|
+
{
|
|
111
|
+
interfacePackage: "@antelopejs/interface-redis",
|
|
112
|
+
package: packageName,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
}).success;
|
|
116
|
+
it("takes an npm package for a dependency", () => {
|
|
117
|
+
(0, chai_1.expect)(install("@antelopejs/redis")).to.equal(true);
|
|
118
|
+
(0, chai_1.expect)(install("redis-module")).to.equal(true);
|
|
119
|
+
});
|
|
120
|
+
it("refuses a git, URL or local source for a dependency", () => {
|
|
121
|
+
(0, chai_1.expect)(install("git+https://github.com/a/b.git")).to.equal(false);
|
|
122
|
+
(0, chai_1.expect)(install("../redis")).to.equal(false);
|
|
123
|
+
(0, chai_1.expect)(install("file:/tmp/redis")).to.equal(false);
|
|
124
|
+
(0, chai_1.expect)(install("github:a/b")).to.equal(false);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../../../src/test/unit/store/store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const storeOperationSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
id: string;
|
|
6
|
+
}, {
|
|
7
|
+
id: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const storeInstallSchema: z.ZodObject<{
|
|
10
|
+
id: z.ZodString;
|
|
11
|
+
} & {
|
|
12
|
+
dependencies: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
13
|
+
interfacePackage: z.ZodString;
|
|
14
|
+
package: z.ZodString;
|
|
15
|
+
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
package: string;
|
|
18
|
+
interfacePackage: string;
|
|
19
|
+
config?: Record<string, unknown> | undefined;
|
|
20
|
+
}, {
|
|
21
|
+
package: string;
|
|
22
|
+
interfacePackage: string;
|
|
23
|
+
config?: Record<string, unknown> | undefined;
|
|
24
|
+
}>, "many">>;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
id: string;
|
|
27
|
+
dependencies?: {
|
|
28
|
+
package: string;
|
|
29
|
+
interfacePackage: string;
|
|
30
|
+
config?: Record<string, unknown> | undefined;
|
|
31
|
+
}[] | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
id: string;
|
|
34
|
+
dependencies?: {
|
|
35
|
+
package: string;
|
|
36
|
+
interfacePackage: string;
|
|
37
|
+
config?: Record<string, unknown> | undefined;
|
|
38
|
+
}[] | undefined;
|
|
39
|
+
}>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.storeInstallSchema = exports.storeOperationSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const CATALOG_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
6
|
+
const CATALOG_ID_MAX_LENGTH = 64;
|
|
7
|
+
exports.storeOperationSchema = zod_1.z.object({
|
|
8
|
+
id: zod_1.z.string().max(CATALOG_ID_MAX_LENGTH).regex(CATALOG_ID_PATTERN),
|
|
9
|
+
});
|
|
10
|
+
const NPM_PACKAGE_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
11
|
+
const NPM_PACKAGE_MAX_LENGTH = 214;
|
|
12
|
+
const MAX_DEPENDENCIES = 20;
|
|
13
|
+
const npmPackageSchema = zod_1.z
|
|
14
|
+
.string()
|
|
15
|
+
.max(NPM_PACKAGE_MAX_LENGTH)
|
|
16
|
+
.regex(NPM_PACKAGE_PATTERN);
|
|
17
|
+
exports.storeInstallSchema = exports.storeOperationSchema.extend({
|
|
18
|
+
dependencies: zod_1.z
|
|
19
|
+
.array(zod_1.z.object({
|
|
20
|
+
interfacePackage: npmPackageSchema,
|
|
21
|
+
package: npmPackageSchema,
|
|
22
|
+
config: zod_1.z.record(zod_1.z.unknown()).optional(),
|
|
23
|
+
}))
|
|
24
|
+
.max(MAX_DEPENDENCIES)
|
|
25
|
+
.optional(),
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=store.schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.schema.js","sourceRoot":"","sources":["../../src/validation/store.schema.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAClD,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAGpB,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;CACpE,CAAC,CAAC;AAMH,MAAM,mBAAmB,GACvB,sDAAsD,CAAC;AACzD,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,MAAM,gBAAgB,GAAG,OAAC;KACvB,MAAM,EAAE;KACR,GAAG,CAAC,sBAAsB,CAAC;KAC3B,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAMjB,QAAA,kBAAkB,GAAG,4BAAoB,CAAC,MAAM,CAAC;IAC5D,YAAY,EAAE,OAAC;SACZ,KAAK,CACJ,OAAC,CAAC,MAAM,CAAC;QACP,gBAAgB,EAAE,gBAAgB;QAClC,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;KACzC,CAAC,CACH;SACA,GAAG,CAAC,gBAAgB,CAAC;SACrB,QAAQ,EAAE;CACd,CAAC,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { MONO_CHIP_CLASS } from "#dms-ui/app/build/utils/monoChip";
|
|
3
|
+
import type { MissingInterface } from "../../../../types/module-store";
|
|
4
|
+
import {
|
|
5
|
+
type DependencyDraft,
|
|
6
|
+
type DependencyDraftError,
|
|
7
|
+
OTHER_PACKAGE_CHOICE,
|
|
8
|
+
validateDependencyDraft,
|
|
9
|
+
} from "../../../utils/module-store-install";
|
|
10
|
+
|
|
11
|
+
interface ModuleStoreDependencyPickerProps {
|
|
12
|
+
/** The interfaces the release needs and no running module implements. */
|
|
13
|
+
missing: MissingInterface[];
|
|
14
|
+
/** One draft per missing interface, in the same order. */
|
|
15
|
+
drafts: DependencyDraft[];
|
|
16
|
+
/** Confirm was tried: the fields say what is wrong. */
|
|
17
|
+
showErrors?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ModuleStoreDependencyPickerEmits {
|
|
21
|
+
update: [index: number, patch: Partial<DependencyDraft>];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const props = withDefaults(defineProps<ModuleStoreDependencyPickerProps>(), {
|
|
25
|
+
showErrors: false,
|
|
26
|
+
});
|
|
27
|
+
const emit = defineEmits<ModuleStoreDependencyPickerEmits>();
|
|
28
|
+
const { t } = useI18n();
|
|
29
|
+
|
|
30
|
+
const CONFIG_PLACEHOLDER = "{}";
|
|
31
|
+
const CONFIG_ROWS = 3;
|
|
32
|
+
|
|
33
|
+
const groups = computed(() =>
|
|
34
|
+
props.missing.map((missing, index) => {
|
|
35
|
+
const draft = props.drafts[index];
|
|
36
|
+
const errors =
|
|
37
|
+
props.showErrors && draft ? validateDependencyDraft(draft) : {};
|
|
38
|
+
return {
|
|
39
|
+
missing,
|
|
40
|
+
draft,
|
|
41
|
+
errors,
|
|
42
|
+
items: [
|
|
43
|
+
...missing.candidates.map((candidate) => ({
|
|
44
|
+
label: candidate.name,
|
|
45
|
+
description: candidate.package,
|
|
46
|
+
value: candidate.package,
|
|
47
|
+
})),
|
|
48
|
+
{
|
|
49
|
+
label: t("modules.store.install_dialog.other"),
|
|
50
|
+
value: OTHER_PACKAGE_CHOICE,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
function errorText(error: DependencyDraftError | undefined) {
|
|
58
|
+
return error ? t(`modules.store.install_dialog.errors.${error}`) : undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Sends `field` of draft `index` as the control typed it. */
|
|
62
|
+
function updateField(
|
|
63
|
+
index: number,
|
|
64
|
+
field: keyof DependencyDraft,
|
|
65
|
+
value: unknown,
|
|
66
|
+
): void {
|
|
67
|
+
emit("update", index, { [field]: String(value ?? "") });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function fieldId(index: number, field: string): string {
|
|
71
|
+
return `store-dependency-${index}-${field}`;
|
|
72
|
+
}
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<div class="flex flex-col gap-4">
|
|
77
|
+
<section
|
|
78
|
+
v-for="(group, index) in groups"
|
|
79
|
+
:key="group.missing.interfacePackage"
|
|
80
|
+
class="flex flex-col gap-2.5"
|
|
81
|
+
:aria-labelledby="fieldId(index, 'title')"
|
|
82
|
+
>
|
|
83
|
+
<h4
|
|
84
|
+
:id="fieldId(index, 'title')"
|
|
85
|
+
class="text-highlighted text-[13px] font-semibold"
|
|
86
|
+
>
|
|
87
|
+
<code :class="[MONO_CHIP_CLASS, 'bg-elevated text-xs']">
|
|
88
|
+
{{ group.missing.interfacePackage }}
|
|
89
|
+
</code>
|
|
90
|
+
</h4>
|
|
91
|
+
<template v-if="group.draft">
|
|
92
|
+
<URadioGroup
|
|
93
|
+
:model-value="group.draft.choice"
|
|
94
|
+
:items="group.items"
|
|
95
|
+
size="sm"
|
|
96
|
+
:aria-labelledby="fieldId(index, 'title')"
|
|
97
|
+
@update:model-value="updateField(index, 'choice', $event)"
|
|
98
|
+
/>
|
|
99
|
+
<UFormField
|
|
100
|
+
v-if="group.draft.choice === OTHER_PACKAGE_CHOICE"
|
|
101
|
+
:label="t('modules.store.install_dialog.package_label')"
|
|
102
|
+
:error="errorText(group.errors.package)"
|
|
103
|
+
>
|
|
104
|
+
<UInput
|
|
105
|
+
:id="fieldId(index, 'package')"
|
|
106
|
+
:model-value="group.draft.otherPackage"
|
|
107
|
+
class="w-full font-mono"
|
|
108
|
+
autocomplete="off"
|
|
109
|
+
spellcheck="false"
|
|
110
|
+
:placeholder="t('modules.store.install_dialog.package_placeholder')"
|
|
111
|
+
@update:model-value="updateField(index, 'otherPackage', $event)"
|
|
112
|
+
/>
|
|
113
|
+
</UFormField>
|
|
114
|
+
<UFormField
|
|
115
|
+
:label="t('modules.store.install_dialog.config_label')"
|
|
116
|
+
:hint="t('modules.store.install_dialog.config_hint')"
|
|
117
|
+
:error="errorText(group.errors.config)"
|
|
118
|
+
>
|
|
119
|
+
<UTextarea
|
|
120
|
+
:id="fieldId(index, 'config')"
|
|
121
|
+
:model-value="group.draft.config"
|
|
122
|
+
class="w-full font-mono text-xs"
|
|
123
|
+
:rows="CONFIG_ROWS"
|
|
124
|
+
autoresize
|
|
125
|
+
spellcheck="false"
|
|
126
|
+
:placeholder="CONFIG_PLACEHOLDER"
|
|
127
|
+
@update:model-value="updateField(index, 'config', $event)"
|
|
128
|
+
/>
|
|
129
|
+
</UFormField>
|
|
130
|
+
</template>
|
|
131
|
+
</section>
|
|
132
|
+
<p class="text-muted text-xs">
|
|
133
|
+
{{ t("modules.store.install_dialog.note") }}
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
</template>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import DmsCopyButton from "#dms-ui/app/components/copy/CopyButton.vue";
|
|
3
|
+
import type { StoreListingEntry } from "../../../../types/module-store";
|
|
4
|
+
|
|
5
|
+
interface ModuleStoreRequirementsProps {
|
|
6
|
+
/** The store module whose requirements the tile spells out. */
|
|
7
|
+
entry: StoreListingEntry;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props = defineProps<ModuleStoreRequirementsProps>();
|
|
11
|
+
const { t } = useI18n();
|
|
12
|
+
|
|
13
|
+
const LIST_SEPARATOR = ", ";
|
|
14
|
+
|
|
15
|
+
const requirement = computed(() => props.entry.frontendRequirement);
|
|
16
|
+
const missingInterfaces = computed(() =>
|
|
17
|
+
props.entry.missingInterfaces
|
|
18
|
+
.map((missing) => missing.interfacePackage)
|
|
19
|
+
.join(LIST_SEPARATOR),
|
|
20
|
+
);
|
|
21
|
+
const dependents = computed(() => props.entry.dependents.join(LIST_SEPARATOR));
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<!-- The release needs another dms-frontend: what to run, what it breaks.
|
|
26
|
+
The store never moves dms-frontend itself. -->
|
|
27
|
+
<div
|
|
28
|
+
v-if="requirement"
|
|
29
|
+
class="flex flex-col gap-1.5 rounded-[8px] bg-(--ui-warning)/8 px-2.5 py-1.5 text-xs text-(--ui-warning)"
|
|
30
|
+
>
|
|
31
|
+
<p>
|
|
32
|
+
{{
|
|
33
|
+
t("modules.store.frontend_requirement.needs", {
|
|
34
|
+
range: requirement.range,
|
|
35
|
+
running: requirement.running,
|
|
36
|
+
})
|
|
37
|
+
}}
|
|
38
|
+
</p>
|
|
39
|
+
<template v-if="requirement.target">
|
|
40
|
+
<p v-if="requirement.command" class="text-toned">
|
|
41
|
+
{{
|
|
42
|
+
t("modules.store.frontend_requirement.run", {
|
|
43
|
+
target: requirement.target,
|
|
44
|
+
})
|
|
45
|
+
}}
|
|
46
|
+
</p>
|
|
47
|
+
<div
|
|
48
|
+
v-if="requirement.command"
|
|
49
|
+
class="text-highlighted flex min-w-0 items-center gap-1 rounded-[6px] border border-(--ui-border) bg-(--dms-bg-muted) ps-2 font-mono text-[11px]"
|
|
50
|
+
>
|
|
51
|
+
<code class="min-w-0 flex-1 truncate" :title="requirement.command">
|
|
52
|
+
{{ requirement.command }}
|
|
53
|
+
</code>
|
|
54
|
+
<DmsCopyButton :value="requirement.command" />
|
|
55
|
+
</div>
|
|
56
|
+
<template v-if="requirement.breaks.length > 0">
|
|
57
|
+
<p>
|
|
58
|
+
{{
|
|
59
|
+
t("modules.store.frontend_requirement.breaks", {
|
|
60
|
+
target: requirement.target,
|
|
61
|
+
})
|
|
62
|
+
}}
|
|
63
|
+
</p>
|
|
64
|
+
<ul class="text-toned flex flex-col gap-0.5">
|
|
65
|
+
<li
|
|
66
|
+
v-for="layer in requirement.breaks"
|
|
67
|
+
:key="layer.name"
|
|
68
|
+
class="flex min-w-0 items-baseline gap-1.5"
|
|
69
|
+
>
|
|
70
|
+
<span class="truncate font-mono">{{ layer.name }}</span>
|
|
71
|
+
<span class="text-dimmed shrink-0">
|
|
72
|
+
{{
|
|
73
|
+
t("modules.store.frontend_requirement.supports", {
|
|
74
|
+
range: layer.range,
|
|
75
|
+
})
|
|
76
|
+
}}
|
|
77
|
+
</span>
|
|
78
|
+
</li>
|
|
79
|
+
</ul>
|
|
80
|
+
</template>
|
|
81
|
+
</template>
|
|
82
|
+
<p v-else class="text-toned">
|
|
83
|
+
{{ t("modules.store.frontend_requirement.no_target") }}
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<p
|
|
88
|
+
v-if="missingInterfaces"
|
|
89
|
+
class="text-toned truncate text-xs"
|
|
90
|
+
:title="missingInterfaces"
|
|
91
|
+
>
|
|
92
|
+
{{ t("modules.store.requires", { interfaces: missingInterfaces }) }}
|
|
93
|
+
</p>
|
|
94
|
+
|
|
95
|
+
<p v-if="dependents" class="text-xs text-(--ui-warning)">
|
|
96
|
+
{{ t("modules.store.used_by", { modules: dependents }) }}
|
|
97
|
+
</p>
|
|
98
|
+
</template>
|