@platforma-sdk/package-builder-lib 1.1.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/assets/conda-dockerfile.template +45 -0
- package/assets/python-dockerfile.template +22 -0
- package/dist/_virtual/_rolldown/runtime.cjs +33 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/core/archive.cjs +52 -0
- package/dist/core/archive.cjs.map +1 -0
- package/dist/core/archive.js +47 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/conda/builder.cjs +226 -0
- package/dist/core/conda/builder.cjs.map +1 -0
- package/dist/core/conda/builder.js +220 -0
- package/dist/core/conda/builder.js.map +1 -0
- package/dist/core/conda/validate-spec.cjs +76 -0
- package/dist/core/conda/validate-spec.cjs.map +1 -0
- package/dist/core/conda/validate-spec.js +73 -0
- package/dist/core/conda/validate-spec.js.map +1 -0
- package/dist/core/core.cjs +403 -0
- package/dist/core/core.cjs.map +1 -0
- package/dist/core/core.d.ts +82 -0
- package/dist/core/core.d.ts.map +1 -0
- package/dist/core/core.js +397 -0
- package/dist/core/core.js.map +1 -0
- package/dist/core/docker-conda.cjs +75 -0
- package/dist/core/docker-conda.cjs.map +1 -0
- package/dist/core/docker-conda.js +71 -0
- package/dist/core/docker-conda.js.map +1 -0
- package/dist/core/docker-python.cjs +147 -0
- package/dist/core/docker-python.cjs.map +1 -0
- package/dist/core/docker-python.js +144 -0
- package/dist/core/docker-python.js.map +1 -0
- package/dist/core/docker.cjs +223 -0
- package/dist/core/docker.cjs.map +1 -0
- package/dist/core/docker.js +207 -0
- package/dist/core/docker.js.map +1 -0
- package/dist/core/envs.cjs +58 -0
- package/dist/core/envs.cjs.map +1 -0
- package/dist/core/envs.d.ts +26 -0
- package/dist/core/envs.d.ts.map +1 -0
- package/dist/core/envs.js +51 -0
- package/dist/core/envs.js.map +1 -0
- package/dist/core/package-info.cjs +450 -0
- package/dist/core/package-info.cjs.map +1 -0
- package/dist/core/package-info.d.ts +57 -0
- package/dist/core/package-info.d.ts.map +1 -0
- package/dist/core/package-info.js +447 -0
- package/dist/core/package-info.js.map +1 -0
- package/dist/core/paths.cjs +15 -0
- package/dist/core/paths.cjs.map +1 -0
- package/dist/core/paths.js +14 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/resolver.cjs +99 -0
- package/dist/core/resolver.cjs.map +1 -0
- package/dist/core/resolver.js +95 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/schemas/artifacts.cjs +136 -0
- package/dist/core/schemas/artifacts.cjs.map +1 -0
- package/dist/core/schemas/artifacts.d.ts +280 -0
- package/dist/core/schemas/artifacts.d.ts.map +1 -0
- package/dist/core/schemas/artifacts.js +122 -0
- package/dist/core/schemas/artifacts.js.map +1 -0
- package/dist/core/schemas/entrypoints.cjs +43 -0
- package/dist/core/schemas/entrypoints.cjs.map +1 -0
- package/dist/core/schemas/entrypoints.d.ts +32 -0
- package/dist/core/schemas/entrypoints.d.ts.map +1 -0
- package/dist/core/schemas/entrypoints.js +41 -0
- package/dist/core/schemas/entrypoints.js.map +1 -0
- package/dist/core/schemas/sw-json.cjs +111 -0
- package/dist/core/schemas/sw-json.cjs.map +1 -0
- package/dist/core/schemas/sw-json.js +110 -0
- package/dist/core/schemas/sw-json.js.map +1 -0
- package/dist/core/storage.cjs +86 -0
- package/dist/core/storage.cjs.map +1 -0
- package/dist/core/storage.js +83 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/sw-json-render.cjs +327 -0
- package/dist/core/sw-json-render.cjs.map +1 -0
- package/dist/core/sw-json-render.js +322 -0
- package/dist/core/sw-json-render.js.map +1 -0
- package/dist/core/util.cjs +313 -0
- package/dist/core/util.cjs.map +1 -0
- package/dist/core/util.d.ts +66 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/core/util.js +281 -0
- package/dist/core/util.js.map +1 -0
- package/dist/defaults.cjs +54 -0
- package/dist/defaults.cjs.map +1 -0
- package/dist/defaults.d.ts +21 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +37 -0
- package/dist/defaults.js.map +1 -0
- package/dist/index.cjs +31 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
- package/src/__test__/Dockerfile +1 -0
- package/src/__test__/docker.test.ts +67 -0
- package/src/__test__/package.json +39 -0
- package/src/__test__/python-example/main.py +1 -0
- package/src/__test__/python-example/requirements.txt +0 -0
- package/src/__test__/vite.config.mts +7 -0
- package/src/core/__tests__/docker-conda.test.ts +145 -0
- package/src/core/__tests__/docker-entrypoint-generation.test.ts +119 -0
- package/src/core/__tests__/docker-python.test.ts +374 -0
- package/src/core/__tests__/publish-docker-images.test.ts +309 -0
- package/src/core/archive.ts +102 -0
- package/src/core/conda/builder.test.ts +71 -0
- package/src/core/conda/builder.ts +384 -0
- package/src/core/conda/validate-spec.test.ts +213 -0
- package/src/core/conda/validate-spec.ts +107 -0
- package/src/core/core.ts +835 -0
- package/src/core/docker-conda.ts +149 -0
- package/src/core/docker-python.ts +283 -0
- package/src/core/docker.ts +300 -0
- package/src/core/envs.ts +31 -0
- package/src/core/package-info.test.ts +82 -0
- package/src/core/package-info.ts +843 -0
- package/src/core/paths.ts +16 -0
- package/src/core/resolver.ts +195 -0
- package/src/core/schemas/artifacts.test.ts +72 -0
- package/src/core/schemas/artifacts.ts +279 -0
- package/src/core/schemas/entrypoints.test.ts +171 -0
- package/src/core/schemas/entrypoints.ts +150 -0
- package/src/core/schemas/sw-json.ts +216 -0
- package/src/core/schemas/test-artifacts.ts +362 -0
- package/src/core/storage.ts +125 -0
- package/src/core/sw-json-render.test.ts +215 -0
- package/src/core/sw-json-render.ts +682 -0
- package/src/core/util.ts +390 -0
- package/src/defaults.ts +38 -0
- package/src/index.ts +31 -0
- package/src/requirements.txt +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_util = require("./util.cjs");
|
|
3
|
+
const require_sw_json = require("./schemas/sw-json.cjs");
|
|
4
|
+
let node_fs = require("node:fs");
|
|
5
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_runtime.__toESM(node_path);
|
|
8
|
+
//#region src/core/resolver.ts
|
|
9
|
+
const compiledSoftwareSuffix = ".sw.json";
|
|
10
|
+
const compiledAssetSuffix = ".as.json";
|
|
11
|
+
function descriptorFilePath(packageRoot, entrypointType, entrypointName) {
|
|
12
|
+
const typeSuffix = entrypointType === "software" ? compiledSoftwareSuffix : compiledAssetSuffix;
|
|
13
|
+
if (!entrypointName) return node_path.default.resolve(packageRoot, "dist", "tengo", entrypointType);
|
|
14
|
+
return node_path.default.resolve(packageRoot, "dist", "tengo", entrypointType, `${entrypointName}${typeSuffix}`);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Read and parse 'sw.json' descriptor file from given path.
|
|
18
|
+
*
|
|
19
|
+
* @param packageRoot: string - root directory of the package that contains software descriptor
|
|
20
|
+
* @param packageName: string - name of the package from <packageRoot>/package.json
|
|
21
|
+
* @param entrypointName: string - name of entrypoint with software descriptor
|
|
22
|
+
*
|
|
23
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
24
|
+
*/
|
|
25
|
+
function readSwJsonFile(packageRoot, packageName, entrypointName) {
|
|
26
|
+
return readDescriptorFile(packageName, entrypointName, descriptorFilePath(packageRoot, "software", entrypointName));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read 'sw.json' or 'as.json' descriptor file from given path and provide it along with metadata of where it came from
|
|
30
|
+
*
|
|
31
|
+
* @param packageNameForDescriptor: string - name of the package that contains this descriptor
|
|
32
|
+
* @param entrypointForDescriptor: string - name of entrypoint that contains this descriptor inside given package
|
|
33
|
+
* @param descriptorFilePath: string - path to the descriptor file
|
|
34
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
35
|
+
*/
|
|
36
|
+
function readDescriptorFile(packageNameForDescriptor, entrypointForDescriptor, descriptorFilePath) {
|
|
37
|
+
if (!node_fs.default.existsSync(descriptorFilePath)) throw require_util.CLIError(`entrypoint '${entrypointForDescriptor}' not found in '${descriptorFilePath}'`);
|
|
38
|
+
const swJsonContent = node_fs.default.readFileSync(descriptorFilePath);
|
|
39
|
+
const result = require_sw_json.swJsonSchema.safeParse(JSON.parse(swJsonContent.toString()));
|
|
40
|
+
if (!result.success) throw require_util.CLIError(require_util.formatZodIssues(result.error.issues));
|
|
41
|
+
return {
|
|
42
|
+
id: {
|
|
43
|
+
package: packageNameForDescriptor,
|
|
44
|
+
name: entrypointForDescriptor
|
|
45
|
+
},
|
|
46
|
+
...result.data
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve package dependency and read software descriptor from it.
|
|
51
|
+
*
|
|
52
|
+
* @param logger: winston.Logger - logger instance
|
|
53
|
+
* @param currentPackageRoot: string - root directory of the current package
|
|
54
|
+
* @param dependencyPackageName: string - name of the dependency to search
|
|
55
|
+
* @param dependencyEntrypointName: string - name of the entrypooint inside dependency package
|
|
56
|
+
*
|
|
57
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
58
|
+
*/
|
|
59
|
+
function resolveDependency(logger, currentPackageRoot, dependencyPackageName, dependencyEntrypointName) {
|
|
60
|
+
return readSwJsonFile(require_util.findInstalledModule(logger, dependencyPackageName, currentPackageRoot), dependencyPackageName, dependencyEntrypointName);
|
|
61
|
+
}
|
|
62
|
+
function resolveRunEnvironment(logger, packageRoot, packageName, envName, requireType) {
|
|
63
|
+
const [pkgName, id] = require_util.rSplit(envName, ":", 2);
|
|
64
|
+
const swDescriptor = pkgName === "" ? readSwJsonFile(packageRoot, packageName, id) : resolveDependency(logger, packageRoot, pkgName, id);
|
|
65
|
+
if (!swDescriptor.runEnv) throw require_util.CLIError(`software '${envName}' cannot be used as run environment (no 'runEnv' section in entrypoint descriptor)`);
|
|
66
|
+
const runEnv = swDescriptor.runEnv;
|
|
67
|
+
if (runEnv.type !== requireType) {
|
|
68
|
+
logger.error(`run environment '${envName}' type '${runEnv.type}' differs from declared package type '${requireType}'`);
|
|
69
|
+
throw require_util.CLIError(`incompatible environment: env type '${runEnv.type}' != package type '${requireType}'`);
|
|
70
|
+
}
|
|
71
|
+
switch (runEnv.type) {
|
|
72
|
+
case "python": return {
|
|
73
|
+
name: envName,
|
|
74
|
+
...runEnv,
|
|
75
|
+
type: "python",
|
|
76
|
+
["python-version"]: runEnv["python-version"] ?? ""
|
|
77
|
+
};
|
|
78
|
+
case "R": return {
|
|
79
|
+
name: envName,
|
|
80
|
+
...runEnv,
|
|
81
|
+
type: "R",
|
|
82
|
+
["r-version"]: runEnv["r-version"] ?? ""
|
|
83
|
+
};
|
|
84
|
+
case "java": return {
|
|
85
|
+
name: envName,
|
|
86
|
+
...runEnv,
|
|
87
|
+
type: "java",
|
|
88
|
+
["java-version"]: runEnv["java-version"] ?? ""
|
|
89
|
+
};
|
|
90
|
+
default:
|
|
91
|
+
require_util.assertNever(runEnv.type);
|
|
92
|
+
throw new Error("renderer logic error: resolveRunEnvironment does not cover all run environment types");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
exports.descriptorFilePath = descriptorFilePath;
|
|
97
|
+
exports.resolveRunEnvironment = resolveRunEnvironment;
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=resolver.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.cjs","names":["path","fs"],"sources":["../../src/core/resolver.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"node:fs\";\nimport type winston from \"winston\";\n\nimport * as swJson from \"./schemas/sw-json\";\nimport type * as artifacts from \"./schemas/artifacts\";\nimport type * as entrypoint from \"./schemas/entrypoints\";\nimport * as util from \"./util\";\n\nexport const compiledSoftwareSuffix = \".sw.json\";\nexport const compiledAssetSuffix = \".as.json\";\n\nexport function descriptorFilePath(\n packageRoot: string,\n entrypointType: Extract<entrypoint.EntrypointType, \"software\" | \"asset\">,\n entrypointName?: string,\n): string {\n const typeSuffix = entrypointType === \"software\" ? compiledSoftwareSuffix : compiledAssetSuffix;\n\n if (!entrypointName) {\n return path.resolve(packageRoot, \"dist\", \"tengo\", entrypointType);\n }\n\n return path.resolve(\n packageRoot,\n \"dist\",\n \"tengo\",\n entrypointType,\n `${entrypointName}${typeSuffix}`,\n );\n}\n\n/**\n * Read and parse 'sw.json' descriptor file from given path.\n *\n * @param packageRoot: string - root directory of the package that contains software descriptor\n * @param packageName: string - name of the package from <packageRoot>/package.json\n * @param entrypointName: string - name of entrypoint with software descriptor\n *\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function readSwJsonFile(\n packageRoot: string,\n packageName: string,\n entrypointName: string,\n): swJson.swJsonType {\n const filePath = descriptorFilePath(packageRoot, \"software\", entrypointName);\n return readDescriptorFile(packageName, entrypointName, filePath);\n}\n\n/**\n * Read 'sw.json' or 'as.json' descriptor file from given path and provide it along with metadata of where it came from\n *\n * @param packageNameForDescriptor: string - name of the package that contains this descriptor\n * @param entrypointForDescriptor: string - name of entrypoint that contains this descriptor inside given package\n * @param descriptorFilePath: string - path to the descriptor file\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function readDescriptorFile(\n packageNameForDescriptor: string,\n entrypointForDescriptor: string,\n descriptorFilePath: string,\n): swJson.swJsonType {\n if (!fs.existsSync(descriptorFilePath)) {\n throw util.CLIError(\n `entrypoint '${entrypointForDescriptor}' not found in '${descriptorFilePath}'`,\n );\n }\n\n const swJsonContent = fs.readFileSync(descriptorFilePath);\n const result = swJson.swJsonSchema.safeParse(JSON.parse(swJsonContent.toString()));\n\n if (!result.success) {\n throw util.CLIError(util.formatZodIssues(result.error.issues));\n }\n\n return {\n id: {\n package: packageNameForDescriptor,\n name: entrypointForDescriptor,\n },\n ...result.data,\n };\n}\n\n/**\n * Resolve package dependency and read software descriptor from it.\n *\n * @param logger: winston.Logger - logger instance\n * @param currentPackageRoot: string - root directory of the current package\n * @param dependencyPackageName: string - name of the dependency to search\n * @param dependencyEntrypointName: string - name of the entrypooint inside dependency package\n *\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function resolveDependency(\n logger: winston.Logger,\n currentPackageRoot: string,\n dependencyPackageName: string,\n dependencyEntrypointName: string,\n): swJson.swJsonType {\n const dependencyPath = util.findInstalledModule(\n logger,\n dependencyPackageName,\n currentPackageRoot,\n );\n return readSwJsonFile(dependencyPath, dependencyPackageName, dependencyEntrypointName);\n}\n\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"java\",\n): swJson.runEnvDependencyJava;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"python\",\n): swJson.runEnvDependencyPython;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"R\",\n): swJson.runEnvDependencyR;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: artifacts.runEnvironmentType,\n): swJson.runEnvDependency {\n const [pkgName, id] = util.rSplit(envName, \":\", 2);\n const swDescriptor =\n pkgName === \"\"\n ? readSwJsonFile(packageRoot, packageName, id)\n : resolveDependency(logger, packageRoot, pkgName, id);\n\n if (!swDescriptor.runEnv) {\n throw util.CLIError(\n `software '${envName}' cannot be used as run environment (no 'runEnv' section in entrypoint descriptor)`,\n );\n }\n\n const runEnv = swDescriptor.runEnv;\n\n if (runEnv.type !== requireType) {\n logger.error(\n `run environment '${envName}' type '${runEnv.type}' differs from declared package type '${requireType}'`,\n );\n throw util.CLIError(\n `incompatible environment: env type '${runEnv.type}' != package type '${requireType}'`,\n );\n }\n\n switch (runEnv.type) {\n case \"python\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"python\",\n [\"python-version\"]: runEnv[\"python-version\"] ?? \"\",\n };\n }\n case \"R\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"R\",\n [\"r-version\"]: runEnv[\"r-version\"] ?? \"\",\n };\n }\n case \"java\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"java\",\n [\"java-version\"]: runEnv[\"java-version\"] ?? \"\",\n };\n }\n default:\n util.assertNever(runEnv.type);\n throw new Error(\n \"renderer logic error: resolveRunEnvironment does not cover all run environment types\",\n ); // calm down the linter\n }\n}\n"],"mappings":";;;;;;;;AASA,MAAa,yBAAyB;AACtC,MAAa,sBAAsB;AAEnC,SAAgB,mBACd,aACA,gBACA,gBACQ;CACR,MAAM,aAAa,mBAAmB,aAAa,yBAAyB;AAE5E,KAAI,CAAC,eACH,QAAOA,UAAAA,QAAK,QAAQ,aAAa,QAAQ,SAAS,eAAe;AAGnE,QAAOA,UAAAA,QAAK,QACV,aACA,QACA,SACA,gBACA,GAAG,iBAAiB,aACrB;;;;;;;;;;;AAYH,SAAgB,eACd,aACA,aACA,gBACmB;AAEnB,QAAO,mBAAmB,aAAa,gBADtB,mBAAmB,aAAa,YAAY,eAAe,CACZ;;;;;;;;;;AAWlE,SAAgB,mBACd,0BACA,yBACA,oBACmB;AACnB,KAAI,CAACC,QAAAA,QAAG,WAAW,mBAAmB,CACpC,OAAA,aAAA,SACE,eAAe,wBAAwB,kBAAkB,mBAAmB,GAC7E;CAGH,MAAM,gBAAgBA,QAAAA,QAAG,aAAa,mBAAmB;CACzD,MAAM,SAAA,gBAAA,aAA6B,UAAU,KAAK,MAAM,cAAc,UAAU,CAAC,CAAC;AAElF,KAAI,CAAC,OAAO,QACV,OAAA,aAAA,SAAA,aAAA,gBAAyC,OAAO,MAAM,OAAO,CAAC;AAGhE,QAAO;EACL,IAAI;GACF,SAAS;GACT,MAAM;GACP;EACD,GAAG,OAAO;EACX;;;;;;;;;;;;AAaH,SAAgB,kBACd,QACA,oBACA,uBACA,0BACmB;AAMnB,QAAO,eAAA,aAAA,oBAJL,QACA,uBACA,mBACD,EACqC,uBAAuB,yBAAyB;;AAwBxF,SAAgB,sBACd,QACA,aACA,aACA,SACA,aACyB;CACzB,MAAM,CAAC,SAAS,MAAA,aAAA,OAAkB,SAAS,KAAK,EAAE;CAClD,MAAM,eACJ,YAAY,KACR,eAAe,aAAa,aAAa,GAAG,GAC5C,kBAAkB,QAAQ,aAAa,SAAS,GAAG;AAEzD,KAAI,CAAC,aAAa,OAChB,OAAA,aAAA,SACE,aAAa,QAAQ,oFACtB;CAGH,MAAM,SAAS,aAAa;AAE5B,KAAI,OAAO,SAAS,aAAa;AAC/B,SAAO,MACL,oBAAoB,QAAQ,UAAU,OAAO,KAAK,wCAAwC,YAAY,GACvG;AACD,QAAA,aAAA,SACE,uCAAuC,OAAO,KAAK,qBAAqB,YAAY,GACrF;;AAGH,SAAQ,OAAO,MAAf;EACE,KAAK,SACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,mBAAmB,OAAO,qBAAqB;GACjD;EAEH,KAAK,IACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,cAAc,OAAO,gBAAgB;GACvC;EAEH,KAAK,OACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,iBAAiB,OAAO,mBAAmB;GAC7C;EAEH;AACE,gBAAA,YAAiB,OAAO,KAAK;AAC7B,SAAM,IAAI,MACR,uFACD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { CLIError, assertNever, findInstalledModule, formatZodIssues, rSplit } from "./util.js";
|
|
2
|
+
import { swJsonSchema } from "./schemas/sw-json.js";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
//#region src/core/resolver.ts
|
|
6
|
+
const compiledSoftwareSuffix = ".sw.json";
|
|
7
|
+
const compiledAssetSuffix = ".as.json";
|
|
8
|
+
function descriptorFilePath(packageRoot, entrypointType, entrypointName) {
|
|
9
|
+
const typeSuffix = entrypointType === "software" ? compiledSoftwareSuffix : compiledAssetSuffix;
|
|
10
|
+
if (!entrypointName) return path.resolve(packageRoot, "dist", "tengo", entrypointType);
|
|
11
|
+
return path.resolve(packageRoot, "dist", "tengo", entrypointType, `${entrypointName}${typeSuffix}`);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read and parse 'sw.json' descriptor file from given path.
|
|
15
|
+
*
|
|
16
|
+
* @param packageRoot: string - root directory of the package that contains software descriptor
|
|
17
|
+
* @param packageName: string - name of the package from <packageRoot>/package.json
|
|
18
|
+
* @param entrypointName: string - name of entrypoint with software descriptor
|
|
19
|
+
*
|
|
20
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
21
|
+
*/
|
|
22
|
+
function readSwJsonFile(packageRoot, packageName, entrypointName) {
|
|
23
|
+
return readDescriptorFile(packageName, entrypointName, descriptorFilePath(packageRoot, "software", entrypointName));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Read 'sw.json' or 'as.json' descriptor file from given path and provide it along with metadata of where it came from
|
|
27
|
+
*
|
|
28
|
+
* @param packageNameForDescriptor: string - name of the package that contains this descriptor
|
|
29
|
+
* @param entrypointForDescriptor: string - name of entrypoint that contains this descriptor inside given package
|
|
30
|
+
* @param descriptorFilePath: string - path to the descriptor file
|
|
31
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
32
|
+
*/
|
|
33
|
+
function readDescriptorFile(packageNameForDescriptor, entrypointForDescriptor, descriptorFilePath) {
|
|
34
|
+
if (!fs.existsSync(descriptorFilePath)) throw CLIError(`entrypoint '${entrypointForDescriptor}' not found in '${descriptorFilePath}'`);
|
|
35
|
+
const swJsonContent = fs.readFileSync(descriptorFilePath);
|
|
36
|
+
const result = swJsonSchema.safeParse(JSON.parse(swJsonContent.toString()));
|
|
37
|
+
if (!result.success) throw CLIError(formatZodIssues(result.error.issues));
|
|
38
|
+
return {
|
|
39
|
+
id: {
|
|
40
|
+
package: packageNameForDescriptor,
|
|
41
|
+
name: entrypointForDescriptor
|
|
42
|
+
},
|
|
43
|
+
...result.data
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve package dependency and read software descriptor from it.
|
|
48
|
+
*
|
|
49
|
+
* @param logger: winston.Logger - logger instance
|
|
50
|
+
* @param currentPackageRoot: string - root directory of the current package
|
|
51
|
+
* @param dependencyPackageName: string - name of the dependency to search
|
|
52
|
+
* @param dependencyEntrypointName: string - name of the entrypooint inside dependency package
|
|
53
|
+
*
|
|
54
|
+
* @returns swJson.entrypoint - parsed descriptor with meta information of where it came from
|
|
55
|
+
*/
|
|
56
|
+
function resolveDependency(logger, currentPackageRoot, dependencyPackageName, dependencyEntrypointName) {
|
|
57
|
+
return readSwJsonFile(findInstalledModule(logger, dependencyPackageName, currentPackageRoot), dependencyPackageName, dependencyEntrypointName);
|
|
58
|
+
}
|
|
59
|
+
function resolveRunEnvironment(logger, packageRoot, packageName, envName, requireType) {
|
|
60
|
+
const [pkgName, id] = rSplit(envName, ":", 2);
|
|
61
|
+
const swDescriptor = pkgName === "" ? readSwJsonFile(packageRoot, packageName, id) : resolveDependency(logger, packageRoot, pkgName, id);
|
|
62
|
+
if (!swDescriptor.runEnv) throw CLIError(`software '${envName}' cannot be used as run environment (no 'runEnv' section in entrypoint descriptor)`);
|
|
63
|
+
const runEnv = swDescriptor.runEnv;
|
|
64
|
+
if (runEnv.type !== requireType) {
|
|
65
|
+
logger.error(`run environment '${envName}' type '${runEnv.type}' differs from declared package type '${requireType}'`);
|
|
66
|
+
throw CLIError(`incompatible environment: env type '${runEnv.type}' != package type '${requireType}'`);
|
|
67
|
+
}
|
|
68
|
+
switch (runEnv.type) {
|
|
69
|
+
case "python": return {
|
|
70
|
+
name: envName,
|
|
71
|
+
...runEnv,
|
|
72
|
+
type: "python",
|
|
73
|
+
["python-version"]: runEnv["python-version"] ?? ""
|
|
74
|
+
};
|
|
75
|
+
case "R": return {
|
|
76
|
+
name: envName,
|
|
77
|
+
...runEnv,
|
|
78
|
+
type: "R",
|
|
79
|
+
["r-version"]: runEnv["r-version"] ?? ""
|
|
80
|
+
};
|
|
81
|
+
case "java": return {
|
|
82
|
+
name: envName,
|
|
83
|
+
...runEnv,
|
|
84
|
+
type: "java",
|
|
85
|
+
["java-version"]: runEnv["java-version"] ?? ""
|
|
86
|
+
};
|
|
87
|
+
default:
|
|
88
|
+
assertNever(runEnv.type);
|
|
89
|
+
throw new Error("renderer logic error: resolveRunEnvironment does not cover all run environment types");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { descriptorFilePath, resolveRunEnvironment };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","names":["util.CLIError","util.formatZodIssues","util.findInstalledModule","util.rSplit"],"sources":["../../src/core/resolver.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"node:fs\";\nimport type winston from \"winston\";\n\nimport * as swJson from \"./schemas/sw-json\";\nimport type * as artifacts from \"./schemas/artifacts\";\nimport type * as entrypoint from \"./schemas/entrypoints\";\nimport * as util from \"./util\";\n\nexport const compiledSoftwareSuffix = \".sw.json\";\nexport const compiledAssetSuffix = \".as.json\";\n\nexport function descriptorFilePath(\n packageRoot: string,\n entrypointType: Extract<entrypoint.EntrypointType, \"software\" | \"asset\">,\n entrypointName?: string,\n): string {\n const typeSuffix = entrypointType === \"software\" ? compiledSoftwareSuffix : compiledAssetSuffix;\n\n if (!entrypointName) {\n return path.resolve(packageRoot, \"dist\", \"tengo\", entrypointType);\n }\n\n return path.resolve(\n packageRoot,\n \"dist\",\n \"tengo\",\n entrypointType,\n `${entrypointName}${typeSuffix}`,\n );\n}\n\n/**\n * Read and parse 'sw.json' descriptor file from given path.\n *\n * @param packageRoot: string - root directory of the package that contains software descriptor\n * @param packageName: string - name of the package from <packageRoot>/package.json\n * @param entrypointName: string - name of entrypoint with software descriptor\n *\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function readSwJsonFile(\n packageRoot: string,\n packageName: string,\n entrypointName: string,\n): swJson.swJsonType {\n const filePath = descriptorFilePath(packageRoot, \"software\", entrypointName);\n return readDescriptorFile(packageName, entrypointName, filePath);\n}\n\n/**\n * Read 'sw.json' or 'as.json' descriptor file from given path and provide it along with metadata of where it came from\n *\n * @param packageNameForDescriptor: string - name of the package that contains this descriptor\n * @param entrypointForDescriptor: string - name of entrypoint that contains this descriptor inside given package\n * @param descriptorFilePath: string - path to the descriptor file\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function readDescriptorFile(\n packageNameForDescriptor: string,\n entrypointForDescriptor: string,\n descriptorFilePath: string,\n): swJson.swJsonType {\n if (!fs.existsSync(descriptorFilePath)) {\n throw util.CLIError(\n `entrypoint '${entrypointForDescriptor}' not found in '${descriptorFilePath}'`,\n );\n }\n\n const swJsonContent = fs.readFileSync(descriptorFilePath);\n const result = swJson.swJsonSchema.safeParse(JSON.parse(swJsonContent.toString()));\n\n if (!result.success) {\n throw util.CLIError(util.formatZodIssues(result.error.issues));\n }\n\n return {\n id: {\n package: packageNameForDescriptor,\n name: entrypointForDescriptor,\n },\n ...result.data,\n };\n}\n\n/**\n * Resolve package dependency and read software descriptor from it.\n *\n * @param logger: winston.Logger - logger instance\n * @param currentPackageRoot: string - root directory of the current package\n * @param dependencyPackageName: string - name of the dependency to search\n * @param dependencyEntrypointName: string - name of the entrypooint inside dependency package\n *\n * @returns swJson.entrypoint - parsed descriptor with meta information of where it came from\n */\nexport function resolveDependency(\n logger: winston.Logger,\n currentPackageRoot: string,\n dependencyPackageName: string,\n dependencyEntrypointName: string,\n): swJson.swJsonType {\n const dependencyPath = util.findInstalledModule(\n logger,\n dependencyPackageName,\n currentPackageRoot,\n );\n return readSwJsonFile(dependencyPath, dependencyPackageName, dependencyEntrypointName);\n}\n\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"java\",\n): swJson.runEnvDependencyJava;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"python\",\n): swJson.runEnvDependencyPython;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: \"R\",\n): swJson.runEnvDependencyR;\nexport function resolveRunEnvironment(\n logger: winston.Logger,\n packageRoot: string,\n packageName: string,\n envName: string,\n requireType: artifacts.runEnvironmentType,\n): swJson.runEnvDependency {\n const [pkgName, id] = util.rSplit(envName, \":\", 2);\n const swDescriptor =\n pkgName === \"\"\n ? readSwJsonFile(packageRoot, packageName, id)\n : resolveDependency(logger, packageRoot, pkgName, id);\n\n if (!swDescriptor.runEnv) {\n throw util.CLIError(\n `software '${envName}' cannot be used as run environment (no 'runEnv' section in entrypoint descriptor)`,\n );\n }\n\n const runEnv = swDescriptor.runEnv;\n\n if (runEnv.type !== requireType) {\n logger.error(\n `run environment '${envName}' type '${runEnv.type}' differs from declared package type '${requireType}'`,\n );\n throw util.CLIError(\n `incompatible environment: env type '${runEnv.type}' != package type '${requireType}'`,\n );\n }\n\n switch (runEnv.type) {\n case \"python\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"python\",\n [\"python-version\"]: runEnv[\"python-version\"] ?? \"\",\n };\n }\n case \"R\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"R\",\n [\"r-version\"]: runEnv[\"r-version\"] ?? \"\",\n };\n }\n case \"java\": {\n return {\n name: envName,\n ...runEnv,\n\n type: \"java\",\n [\"java-version\"]: runEnv[\"java-version\"] ?? \"\",\n };\n }\n default:\n util.assertNever(runEnv.type);\n throw new Error(\n \"renderer logic error: resolveRunEnvironment does not cover all run environment types\",\n ); // calm down the linter\n }\n}\n"],"mappings":";;;;;AASA,MAAa,yBAAyB;AACtC,MAAa,sBAAsB;AAEnC,SAAgB,mBACd,aACA,gBACA,gBACQ;CACR,MAAM,aAAa,mBAAmB,aAAa,yBAAyB;AAE5E,KAAI,CAAC,eACH,QAAO,KAAK,QAAQ,aAAa,QAAQ,SAAS,eAAe;AAGnE,QAAO,KAAK,QACV,aACA,QACA,SACA,gBACA,GAAG,iBAAiB,aACrB;;;;;;;;;;;AAYH,SAAgB,eACd,aACA,aACA,gBACmB;AAEnB,QAAO,mBAAmB,aAAa,gBADtB,mBAAmB,aAAa,YAAY,eAAe,CACZ;;;;;;;;;;AAWlE,SAAgB,mBACd,0BACA,yBACA,oBACmB;AACnB,KAAI,CAAC,GAAG,WAAW,mBAAmB,CACpC,OAAMA,SACJ,eAAe,wBAAwB,kBAAkB,mBAAmB,GAC7E;CAGH,MAAM,gBAAgB,GAAG,aAAa,mBAAmB;CACzD,MAAM,SAAA,aAA6B,UAAU,KAAK,MAAM,cAAc,UAAU,CAAC,CAAC;AAElF,KAAI,CAAC,OAAO,QACV,OAAMA,SAAcC,gBAAqB,OAAO,MAAM,OAAO,CAAC;AAGhE,QAAO;EACL,IAAI;GACF,SAAS;GACT,MAAM;GACP;EACD,GAAG,OAAO;EACX;;;;;;;;;;;;AAaH,SAAgB,kBACd,QACA,oBACA,uBACA,0BACmB;AAMnB,QAAO,eALgBC,oBACrB,QACA,uBACA,mBACD,EACqC,uBAAuB,yBAAyB;;AAwBxF,SAAgB,sBACd,QACA,aACA,aACA,SACA,aACyB;CACzB,MAAM,CAAC,SAAS,MAAMC,OAAY,SAAS,KAAK,EAAE;CAClD,MAAM,eACJ,YAAY,KACR,eAAe,aAAa,aAAa,GAAG,GAC5C,kBAAkB,QAAQ,aAAa,SAAS,GAAG;AAEzD,KAAI,CAAC,aAAa,OAChB,OAAMH,SACJ,aAAa,QAAQ,oFACtB;CAGH,MAAM,SAAS,aAAa;AAE5B,KAAI,OAAO,SAAS,aAAa;AAC/B,SAAO,MACL,oBAAoB,QAAQ,UAAU,OAAO,KAAK,wCAAwC,YAAY,GACvG;AACD,QAAMA,SACJ,uCAAuC,OAAO,KAAK,qBAAqB,YAAY,GACrF;;AAGH,SAAQ,OAAO,MAAf;EACE,KAAK,SACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,mBAAmB,OAAO,qBAAqB;GACjD;EAEH,KAAK,IACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,cAAc,OAAO,gBAAgB;GACvC;EAEH,KAAK,OACH,QAAO;GACL,MAAM;GACN,GAAG;GAEH,MAAM;IACL,iBAAiB,OAAO,mBAAmB;GAC7C;EAEH;AACE,eAAiB,OAAO,KAAK;AAC7B,SAAM,IAAI,MACR,uFACD"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_defaults = require("../../defaults.cjs");
|
|
3
|
+
const require_util = require("../util.cjs");
|
|
4
|
+
let zod_v4 = require("zod/v4");
|
|
5
|
+
//#region src/core/schemas/artifacts.ts
|
|
6
|
+
const artifactTypes = [
|
|
7
|
+
"asset",
|
|
8
|
+
"environment",
|
|
9
|
+
"binary",
|
|
10
|
+
"java",
|
|
11
|
+
"python",
|
|
12
|
+
"R",
|
|
13
|
+
"docker",
|
|
14
|
+
"conda"
|
|
15
|
+
];
|
|
16
|
+
const archiveArtifactTypes = [
|
|
17
|
+
"asset",
|
|
18
|
+
"environment",
|
|
19
|
+
"binary",
|
|
20
|
+
"java",
|
|
21
|
+
"python",
|
|
22
|
+
"R",
|
|
23
|
+
"conda"
|
|
24
|
+
];
|
|
25
|
+
const crossplatformTypes = [
|
|
26
|
+
"asset",
|
|
27
|
+
"java",
|
|
28
|
+
"python",
|
|
29
|
+
"R"
|
|
30
|
+
];
|
|
31
|
+
const dockerAutogenTypes = ["python", "conda"];
|
|
32
|
+
function isBuildable(aType) {
|
|
33
|
+
return artifactTypes.includes(aType);
|
|
34
|
+
}
|
|
35
|
+
function isCrossPlatform(aType) {
|
|
36
|
+
return crossplatformTypes.includes(aType);
|
|
37
|
+
}
|
|
38
|
+
const runEnvironmentTypes = [
|
|
39
|
+
"java",
|
|
40
|
+
"python",
|
|
41
|
+
"R"
|
|
42
|
+
];
|
|
43
|
+
const registrySchema = zod_v4.z.strictObject({
|
|
44
|
+
name: zod_v4.z.string(),
|
|
45
|
+
downloadURL: zod_v4.z.string().optional(),
|
|
46
|
+
storageURL: zod_v4.z.string().optional()
|
|
47
|
+
});
|
|
48
|
+
const registryOrRef = zod_v4.z.union([zod_v4.z.string(), registrySchema]);
|
|
49
|
+
const archiveRulesSchema = zod_v4.z.object({
|
|
50
|
+
registry: registryOrRef.default({
|
|
51
|
+
name: require_defaults.BIN_REGISTRY_NAME,
|
|
52
|
+
downloadURL: require_defaults.BIN_REGISTRY_DOWNLOAD_URL
|
|
53
|
+
}),
|
|
54
|
+
name: zod_v4.z.string().optional(),
|
|
55
|
+
version: zod_v4.z.string().optional(),
|
|
56
|
+
root: zod_v4.z.string("package archive content directory is required"),
|
|
57
|
+
roots: zod_v4.z.partialRecord(zod_v4.z.enum(require_util.AllPlatforms), zod_v4.z.string("path to package archive content directory cannot be empty").min(1), { error: (iss) => {
|
|
58
|
+
if (iss.input === void 0) return "list of supported platforms is required: { <platform>: <dir> }\nsupported platforms:\n " + require_util.AllPlatforms.join("\n ");
|
|
59
|
+
return null;
|
|
60
|
+
} }).refine((val) => Object.keys(val).length > 0, { message: "specify at least one platform supported by this software in format: { <platform>: <dir> }\nsupported platforms:\n " + require_util.AllPlatforms.join("\n ") }).describe("please, provide settings only for supported platforms: " + require_util.AllPlatforms.join(", "))
|
|
61
|
+
});
|
|
62
|
+
const dockerRulesSchema = zod_v4.z.object({
|
|
63
|
+
["docker-registry"]: zod_v4.z.string("python software is also automatically shipped as docker image. Docker registry cannot be empty").min(1).default(require_defaults.DOCKER_REGISTRY).describe("registry to use for pushing autogenerated docker image"),
|
|
64
|
+
pkg: zod_v4.z.string().default(require_defaults.DOCKER_PLACEHOLDER_PKG).describe("{pkg} placeholder value to be used in \"cmd\" and arguments (for docker autogeneration)")
|
|
65
|
+
});
|
|
66
|
+
const artifactIDSchema = zod_v4.z.string().regex(/:/, { message: "tengo artifact ID must have <npmPackage>:<artifactName> format, e.g @milaboratory/runenv-java-corretto:21.2.0.4.1" }).describe("ID of tengo build artifact");
|
|
67
|
+
const assetSchema = archiveRulesSchema.omit({ roots: true }).extend({ type: zod_v4.z.literal("asset") }).strict();
|
|
68
|
+
const environmentSchema = archiveRulesSchema.omit({ root: true }).extend({
|
|
69
|
+
type: zod_v4.z.literal("environment"),
|
|
70
|
+
runtime: zod_v4.z.enum(runEnvironmentTypes).describe("type of runtime this run environment provides: 'java', 'python' and so on"),
|
|
71
|
+
["r-version"]: zod_v4.z.string().optional(),
|
|
72
|
+
["python-version"]: zod_v4.z.string().optional(),
|
|
73
|
+
["java-version"]: zod_v4.z.string().optional(),
|
|
74
|
+
envVars: zod_v4.z.array(zod_v4.z.string().regex(/=/, "environment variable should be specified in format: <var-name>=<var-value>, i.e.: MY_ENV=value")).optional(),
|
|
75
|
+
binDir: zod_v4.z.string().describe("path to 'bin' directory to be added to PATH when software uses this run environment")
|
|
76
|
+
});
|
|
77
|
+
const binarySchema = archiveRulesSchema.omit({ root: true }).extend({ type: zod_v4.z.literal("binary") });
|
|
78
|
+
const javaSchema = archiveRulesSchema.omit({ roots: true }).extend({
|
|
79
|
+
type: zod_v4.z.literal("java"),
|
|
80
|
+
environment: artifactIDSchema
|
|
81
|
+
});
|
|
82
|
+
const pipToolsetSchema = zod_v4.z.strictObject({
|
|
83
|
+
toolset: zod_v4.z.literal("pip"),
|
|
84
|
+
requirements: zod_v4.z.string().describe("path to requrements.txt inside package archive")
|
|
85
|
+
});
|
|
86
|
+
const pythonToolsetSchema = zod_v4.z.discriminatedUnion("toolset", [pipToolsetSchema]);
|
|
87
|
+
const pythonSchema = archiveRulesSchema.omit({ roots: true }).extend(dockerRulesSchema.shape).extend({
|
|
88
|
+
type: zod_v4.z.literal("python"),
|
|
89
|
+
environment: artifactIDSchema,
|
|
90
|
+
dependencies: pythonToolsetSchema.optional()
|
|
91
|
+
});
|
|
92
|
+
const rSchema = archiveRulesSchema.omit({ roots: true }).extend({
|
|
93
|
+
type: zod_v4.z.literal("R"),
|
|
94
|
+
environment: artifactIDSchema
|
|
95
|
+
});
|
|
96
|
+
const condaSchema = archiveRulesSchema.omit({ root: true }).extend(dockerRulesSchema.shape).extend({
|
|
97
|
+
type: zod_v4.z.literal("conda"),
|
|
98
|
+
["micromamba-version"]: zod_v4.z.string().default(require_defaults.CONDA_MICROMAMBA_VERSION).describe("version of micromamba to be used to operate with conda environments"),
|
|
99
|
+
["conda-root-dir"]: zod_v4.z.string().default(require_defaults.CONDA_DATA_LOCATION).describe("root directory of conda environment inside package root"),
|
|
100
|
+
spec: zod_v4.z.string().default(require_defaults.CONDA_SOURCE_ENV_SPEC_FILE).describe(`path to conda environment yaml specification relative to package.json`)
|
|
101
|
+
});
|
|
102
|
+
const dockerSchema = zod_v4.z.object({
|
|
103
|
+
type: zod_v4.z.literal("docker"),
|
|
104
|
+
registry: zod_v4.z.string().default(require_defaults.DOCKER_REGISTRY).describe("registry+repository URL to use for pulling this image"),
|
|
105
|
+
context: zod_v4.z.string().refine((val) => val !== "./" && val !== ".", { message: "Context cannot be \"./\" or \".\" - use absolute path or relative path without \"./\" prefix" }).describe("relative path to context directory from folder where command is executed or absolute path to context folder (cannot be \"./\" or \".\")"),
|
|
106
|
+
dockerfile: zod_v4.z.string().default(require_defaults.DOCKER_DOCKERFILE).describe("relative path to 'Dockerfile' file from folder where command is executed or absolute path to the file"),
|
|
107
|
+
pkg: zod_v4.z.string().default(require_defaults.DOCKER_PLACEHOLDER_PKG).describe("{pkg} placeholder value to be used in \"cmd\" and arguments")
|
|
108
|
+
});
|
|
109
|
+
const anyArtifactSchema = zod_v4.z.discriminatedUnion("type", [
|
|
110
|
+
assetSchema,
|
|
111
|
+
environmentSchema,
|
|
112
|
+
binarySchema,
|
|
113
|
+
javaSchema,
|
|
114
|
+
pythonSchema,
|
|
115
|
+
rSchema,
|
|
116
|
+
condaSchema,
|
|
117
|
+
dockerSchema
|
|
118
|
+
]);
|
|
119
|
+
const artifactIndexSchema = zod_v4.z.record(zod_v4.z.string(), anyArtifactSchema);
|
|
120
|
+
//#endregion
|
|
121
|
+
exports.archiveArtifactTypes = archiveArtifactTypes;
|
|
122
|
+
exports.artifactIndexSchema = artifactIndexSchema;
|
|
123
|
+
exports.assetSchema = assetSchema;
|
|
124
|
+
exports.binarySchema = binarySchema;
|
|
125
|
+
exports.condaSchema = condaSchema;
|
|
126
|
+
exports.dockerAutogenTypes = dockerAutogenTypes;
|
|
127
|
+
exports.dockerSchema = dockerSchema;
|
|
128
|
+
exports.environmentSchema = environmentSchema;
|
|
129
|
+
exports.isBuildable = isBuildable;
|
|
130
|
+
exports.isCrossPlatform = isCrossPlatform;
|
|
131
|
+
exports.javaSchema = javaSchema;
|
|
132
|
+
exports.pythonSchema = pythonSchema;
|
|
133
|
+
exports.rSchema = rSchema;
|
|
134
|
+
exports.runEnvironmentTypes = runEnvironmentTypes;
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=artifacts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.cjs","names":["z"],"sources":["../../../src/core/schemas/artifacts.ts"],"sourcesContent":["import { z } from \"zod/v4\";\nimport * as defaults from \"../../defaults\";\nimport * as util from \"../util\";\n\n// All known artifact types\nexport const artifactTypes = [\n \"asset\",\n \"environment\",\n \"binary\",\n \"java\",\n \"python\",\n \"R\",\n \"docker\",\n \"conda\",\n] as const;\nexport type artifactType = (typeof artifactTypes)[number];\n\n// TODO: change these to type definitions, not arrays. This will simplify type narrowing logic throughout the code.\nexport const archiveArtifactTypes: artifactType[] = [\n \"asset\",\n \"environment\",\n \"binary\",\n \"java\",\n \"python\",\n \"R\",\n \"conda\",\n] as const;\nexport const crossplatformTypes: artifactType[] = [\"asset\", \"java\", \"python\", \"R\"] as const;\nexport const dockerAutogenTypes: artifactType[] = [\"python\", \"conda\"] as const;\nexport const dockerArchitectures: util.ArchType[] = [\"x64\"] as const;\n\nexport function isBuildable(aType: artifactType): boolean {\n // All known artifact types are buildable. No exceptions so far.\n return artifactTypes.includes(aType);\n}\n\nexport function isCrossPlatform(aType: artifactType): boolean {\n return crossplatformTypes.includes(aType);\n}\n\nexport const runEnvironmentTypes = [\"java\", \"python\", \"R\"] as const;\nexport type runEnvironmentType = (typeof runEnvironmentTypes)[number];\n\nexport const pythonToolsets = [\"pip\"] as const;\nexport type pythonToolsetName = (typeof pythonToolsets)[number];\n\nexport const registrySchema = z.strictObject({\n name: z.string(),\n downloadURL: z.string().optional(),\n storageURL: z.string().optional(),\n});\nexport type registry = z.infer<typeof registrySchema>;\n\nexport const registryOrRef = z.union([z.string(), registrySchema]);\n\n// common fields for all buildable artifacts\n// TODO: create new type for binary packages\nconst archiveRulesSchema = z.object({\n registry: registryOrRef.default({\n name: defaults.BIN_REGISTRY_NAME,\n downloadURL: defaults.BIN_REGISTRY_DOWNLOAD_URL,\n }),\n\n name: z.string().optional(),\n version: z.string().optional(),\n\n root: z.string(\"package archive content directory is required\"),\n roots: z\n .partialRecord(\n z.enum(\n util.AllPlatforms as [\n (typeof util.AllPlatforms)[number],\n ...(typeof util.AllPlatforms)[number][],\n ],\n ),\n z.string(\"path to package archive content directory cannot be empty\").min(1),\n {\n error: (iss) => {\n if (iss.input === undefined) {\n return (\n \"list of supported platforms is required: { <platform>: <dir> }\\n\" +\n \"supported platforms:\\n \" +\n util.AllPlatforms.join(\"\\n \")\n );\n }\n return null;\n },\n },\n )\n .refine((val) => Object.keys(val).length > 0, {\n message:\n \"specify at least one platform supported by this software in format: { <platform>: <dir> }\\n\" +\n \"supported platforms:\\n \" +\n util.AllPlatforms.join(\"\\n \"),\n })\n .describe(\n \"please, provide settings only for supported platforms: \" + util.AllPlatforms.join(\", \"),\n ),\n});\nexport type archiveRules = z.infer<typeof archiveRulesSchema>;\n\nconst dockerRulesSchema = z.object({\n [\"docker-registry\"]: z\n .string(\n \"python software is also automatically shipped as docker image. Docker registry cannot be empty\",\n )\n .min(1)\n .default(defaults.DOCKER_REGISTRY)\n .describe(\"registry to use for pushing autogenerated docker image\"),\n\n pkg: z\n .string()\n .default(defaults.DOCKER_PLACEHOLDER_PKG)\n .describe(\n '{pkg} placeholder value to be used in \"cmd\" and arguments (for docker autogeneration)',\n ),\n});\n\nexport const artifactIDSchema = z\n .string()\n .regex(/:/, {\n message:\n \"tengo artifact ID must have <npmPackage>:<artifactName> format, e.g @milaboratory/runenv-java-corretto:21.2.0.4.1\",\n })\n .describe(\"ID of tengo build artifact\");\n\nexport type artifactIDString = z.infer<typeof artifactIDSchema>;\n\nexport const assetSchema = archiveRulesSchema\n .omit({ roots: true })\n .extend({ type: z.literal(\"asset\") })\n .strict();\nexport type assetType = z.infer<typeof assetSchema>;\n\nexport const environmentSchema = archiveRulesSchema.omit({ root: true }).extend({\n type: z.literal(\"environment\"),\n\n runtime: z\n .enum(runEnvironmentTypes)\n .describe(\"type of runtime this run environment provides: 'java', 'python' and so on\"),\n\n [\"r-version\"]: z.string().optional(),\n [\"python-version\"]: z.string().optional(),\n [\"java-version\"]: z.string().optional(),\n\n envVars: z\n .array(\n z\n .string()\n .regex(\n /=/,\n \"environment variable should be specified in format: <var-name>=<var-value>, i.e.: MY_ENV=value\",\n ),\n )\n .optional(),\n\n binDir: z\n .string()\n .describe(\n \"path to 'bin' directory to be added to PATH when software uses this run environment\",\n ),\n});\n\nexport type environmentType = z.infer<typeof environmentSchema>;\n\nexport const binarySchema = archiveRulesSchema.omit({ root: true }).extend({\n type: z.literal(\"binary\"),\n});\nexport type binaryType = z.infer<typeof binarySchema>;\n\nexport const javaSchema = archiveRulesSchema.omit({ roots: true }).extend({\n type: z.literal(\"java\"),\n environment: artifactIDSchema,\n});\nexport type javaType = z.infer<typeof javaSchema>;\n\nconst pipToolsetSchema = z.strictObject({\n toolset: z.literal(\"pip\"),\n requirements: z.string().describe(\"path to requrements.txt inside package archive\"),\n});\n\nexport const pythonToolsetSchema = z.discriminatedUnion(\"toolset\", [pipToolsetSchema]);\n\nexport const pythonSchema = archiveRulesSchema\n .omit({ roots: true })\n .extend(dockerRulesSchema.shape)\n .extend({\n type: z.literal(\"python\"),\n\n environment: artifactIDSchema,\n dependencies: pythonToolsetSchema.optional(),\n });\nexport type pythonType = z.infer<typeof pythonSchema>;\n\nexport const rSchema = archiveRulesSchema.omit({ roots: true }).extend({\n type: z.literal(\"R\"),\n environment: artifactIDSchema,\n});\nexport type rType = z.infer<typeof rSchema>;\n\nexport const condaSchema = archiveRulesSchema\n .omit({ root: true })\n .extend(dockerRulesSchema.shape)\n .extend({\n type: z.literal(\"conda\"),\n\n [\"micromamba-version\"]: z\n .string()\n .default(defaults.CONDA_MICROMAMBA_VERSION)\n .describe(\"version of micromamba to be used to operate with conda environments\"),\n [\"conda-root-dir\"]: z\n .string()\n .default(defaults.CONDA_DATA_LOCATION)\n .describe(\"root directory of conda environment inside package root\"),\n\n spec: z\n .string()\n .default(defaults.CONDA_SOURCE_ENV_SPEC_FILE)\n .describe(`path to conda environment yaml specification relative to package.json`),\n });\nexport type condaType = z.infer<typeof condaSchema>;\n\nexport const dockerSchema = z.object({\n type: z.literal(\"docker\"),\n\n registry: z\n .string()\n .default(defaults.DOCKER_REGISTRY)\n .describe(\"registry+repository URL to use for pulling this image\"),\n\n // build from custom Dockerfile\n context: z\n .string()\n .refine((val) => val !== \"./\" && val !== \".\", {\n message:\n 'Context cannot be \"./\" or \".\" - use absolute path or relative path without \"./\" prefix',\n })\n .describe(\n 'relative path to context directory from folder where command is executed or absolute path to context folder (cannot be \"./\" or \".\")',\n ),\n\n dockerfile: z\n .string()\n .default(defaults.DOCKER_DOCKERFILE)\n .describe(\n \"relative path to 'Dockerfile' file from folder where command is executed or absolute path to the file\",\n ),\n\n pkg: z\n .string()\n .default(defaults.DOCKER_PLACEHOLDER_PKG)\n .describe('{pkg} placeholder value to be used in \"cmd\" and arguments'),\n\n // import existing image\n // entrypoint: z\n // .array(z.string())\n // .optional()\n // .describe('replace image\\'s ENTRYPOINT with this value when running container'),\n});\nexport type dockerType = z.infer<typeof dockerSchema>;\n\nexport const anyArtifactSchema = z.discriminatedUnion(\"type\", [\n assetSchema,\n environmentSchema,\n binarySchema,\n javaSchema,\n pythonSchema,\n rSchema,\n condaSchema,\n dockerSchema,\n]);\n\nexport type anyArtifactType = z.infer<typeof anyArtifactSchema>;\n\nexport const artifactIndexSchema = z.record(z.string(), anyArtifactSchema);\nexport type artifactIndexType = z.infer<typeof artifactIndexSchema>;\n\nexport type withType<Typ, Orig> = Orig & { type: Typ };\nexport type withId<T> = T & { id: string };\n"],"mappings":"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"}
|