@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,111 @@
|
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_defaults = require("../../defaults.cjs");
|
|
3
|
+
const require_util = require("../util.cjs");
|
|
4
|
+
const require_artifacts = require("./artifacts.cjs");
|
|
5
|
+
let zod_v4 = require("zod/v4");
|
|
6
|
+
//#region src/core/schemas/sw-json.ts
|
|
7
|
+
const remoteLocationSchema = zod_v4.z.object({
|
|
8
|
+
registry: zod_v4.z.string().describe("name of the registry to use for package download"),
|
|
9
|
+
package: zod_v4.z.string().describe("full package path in registry, e.g. 'common/jdk/21.0.2.13.1-{os}-{arch}.tgz")
|
|
10
|
+
});
|
|
11
|
+
const assetSchema = zod_v4.z.object({
|
|
12
|
+
...remoteLocationSchema.shape,
|
|
13
|
+
url: zod_v4.z.string().describe("asset download URL")
|
|
14
|
+
});
|
|
15
|
+
const dockerSchema = zod_v4.z.object({
|
|
16
|
+
tag: zod_v4.z.string().describe("full image tag to pull on backend side to execute this software"),
|
|
17
|
+
entrypoint: zod_v4.z.array(zod_v4.z.string()).describe("override image's entrypoint"),
|
|
18
|
+
cmd: zod_v4.z.array(zod_v4.z.string()).describe("command to be run in the container"),
|
|
19
|
+
pkg: zod_v4.z.string().default(require_defaults.DOCKER_PLACEHOLDER_PKG).describe("what to substitute in place of \"{pkg}\" variable in \"cmd\" (for artifacts with docker autogeneration)")
|
|
20
|
+
});
|
|
21
|
+
const runEnvironmentSchema = zod_v4.z.object({
|
|
22
|
+
type: zod_v4.z.enum(require_artifacts.runEnvironmentTypes),
|
|
23
|
+
...remoteLocationSchema.shape,
|
|
24
|
+
["r-version"]: zod_v4.z.string().optional(),
|
|
25
|
+
["python-version"]: zod_v4.z.string().optional(),
|
|
26
|
+
["java-version"]: zod_v4.z.string().optional(),
|
|
27
|
+
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(),
|
|
28
|
+
binDir: zod_v4.z.string()
|
|
29
|
+
});
|
|
30
|
+
const runDependencyJavaSchema = runEnvironmentSchema.extend({
|
|
31
|
+
type: zod_v4.z.literal("java"),
|
|
32
|
+
name: zod_v4.z.string().describe("name used to import this package as software dependency of tengo script")
|
|
33
|
+
});
|
|
34
|
+
const runDependencyPythonSchema = runEnvironmentSchema.extend({
|
|
35
|
+
type: zod_v4.z.literal("python"),
|
|
36
|
+
["python-version"]: zod_v4.z.string(),
|
|
37
|
+
name: zod_v4.z.string().describe("name used to import this package as software dependency of tengo script")
|
|
38
|
+
});
|
|
39
|
+
const runDependencyRSchema = runEnvironmentSchema.extend({
|
|
40
|
+
type: zod_v4.z.literal("R"),
|
|
41
|
+
["r-version"]: zod_v4.z.string(),
|
|
42
|
+
name: zod_v4.z.string().describe("name used to import this package as software dependency of tengo script")
|
|
43
|
+
});
|
|
44
|
+
const commonPackageSettingsSchema = zod_v4.z.object({
|
|
45
|
+
cmd: zod_v4.z.array(zod_v4.z.string()).min(1).describe("run given command, appended by args from workflow"),
|
|
46
|
+
envVars: zod_v4.z.array(zod_v4.z.string().regex(/=/, "full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes")).optional()
|
|
47
|
+
});
|
|
48
|
+
const binaryPackageSchema = zod_v4.z.object({
|
|
49
|
+
type: zod_v4.z.literal("binary"),
|
|
50
|
+
...commonPackageSettingsSchema.shape,
|
|
51
|
+
pkg: zod_v4.z.string().optional().describe("location of all package contents in Docker container (default: /app)")
|
|
52
|
+
});
|
|
53
|
+
const javaPackageSettingsSchema = zod_v4.z.object({
|
|
54
|
+
type: zod_v4.z.literal("java"),
|
|
55
|
+
...commonPackageSettingsSchema.shape,
|
|
56
|
+
runEnv: runDependencyJavaSchema
|
|
57
|
+
});
|
|
58
|
+
const pythonPackageSettingsSchema = zod_v4.z.object({
|
|
59
|
+
type: zod_v4.z.literal("python"),
|
|
60
|
+
...commonPackageSettingsSchema.shape,
|
|
61
|
+
runEnv: runDependencyPythonSchema,
|
|
62
|
+
toolset: zod_v4.z.string(),
|
|
63
|
+
dependencies: zod_v4.z.record(zod_v4.z.string(), zod_v4.z.string()).describe("paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'")
|
|
64
|
+
});
|
|
65
|
+
const rPackageSettingsSchema = zod_v4.z.object({
|
|
66
|
+
type: zod_v4.z.literal("R"),
|
|
67
|
+
...commonPackageSettingsSchema.shape,
|
|
68
|
+
runEnv: runDependencyRSchema,
|
|
69
|
+
toolset: zod_v4.z.string(),
|
|
70
|
+
dependencies: zod_v4.z.record(zod_v4.z.string(), zod_v4.z.string()).describe("paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'")
|
|
71
|
+
});
|
|
72
|
+
const condaPackageSchema = zod_v4.z.object({
|
|
73
|
+
type: zod_v4.z.literal("conda"),
|
|
74
|
+
...commonPackageSettingsSchema.shape,
|
|
75
|
+
["micromamba-version"]: zod_v4.z.string().describe("version of micromamba to be used to operate with conda environments"),
|
|
76
|
+
["conda-root-dir"]: zod_v4.z.string().default(require_defaults.CONDA_DATA_LOCATION).describe("root directory of conda environment inside package root"),
|
|
77
|
+
spec: zod_v4.z.string().describe("location of spec.yaml describing conda environment, relative to package root.")
|
|
78
|
+
});
|
|
79
|
+
const remoteSoftwareSchema = zod_v4.z.union([
|
|
80
|
+
remoteLocationSchema.extend(binaryPackageSchema.shape),
|
|
81
|
+
remoteLocationSchema.extend(javaPackageSettingsSchema.shape),
|
|
82
|
+
remoteLocationSchema.extend(pythonPackageSettingsSchema.shape),
|
|
83
|
+
remoteLocationSchema.extend(rPackageSettingsSchema.shape),
|
|
84
|
+
remoteLocationSchema.extend(condaPackageSchema.shape)
|
|
85
|
+
]);
|
|
86
|
+
const localLocationSchema = zod_v4.z.object({
|
|
87
|
+
hash: zod_v4.z.string().describe("hash of software directory. Makes deduplication to work properly when you actively develop software"),
|
|
88
|
+
path: zod_v4.z.string().describe("absolute path to root directory of software on local host")
|
|
89
|
+
});
|
|
90
|
+
const localSoftwareSchema = zod_v4.z.discriminatedUnion("type", [
|
|
91
|
+
localLocationSchema.extend(binaryPackageSchema.shape),
|
|
92
|
+
localLocationSchema.extend(javaPackageSettingsSchema.shape),
|
|
93
|
+
localLocationSchema.extend(pythonPackageSettingsSchema.shape),
|
|
94
|
+
localLocationSchema.extend(rPackageSettingsSchema.shape),
|
|
95
|
+
localLocationSchema.extend(condaPackageSchema.shape)
|
|
96
|
+
]);
|
|
97
|
+
const swJsonSchema = zod_v4.z.object({
|
|
98
|
+
isDev: zod_v4.z.boolean().optional(),
|
|
99
|
+
asset: assetSchema.optional(),
|
|
100
|
+
binary: remoteSoftwareSchema.optional(),
|
|
101
|
+
docker: dockerSchema.optional(),
|
|
102
|
+
runEnv: runEnvironmentSchema.optional(),
|
|
103
|
+
local: localSoftwareSchema.optional()
|
|
104
|
+
}).refine((data) => require_util.toInt(data.runEnv) + require_util.toInt(data.binary || data.docker) + require_util.toInt(data.asset) + require_util.toInt(data.local) == 1, {
|
|
105
|
+
message: "entrypoint cannot point to several packages at once: choose 'environment', 'binary', 'asset', 'conda' or 'local'",
|
|
106
|
+
path: ["environment | binary | asset | conda | local"]
|
|
107
|
+
});
|
|
108
|
+
//#endregion
|
|
109
|
+
exports.swJsonSchema = swJsonSchema;
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=sw-json.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-json.cjs","names":["z"],"sources":["../../../src/core/schemas/sw-json.ts"],"sourcesContent":["import { z } from \"zod/v4\";\nimport * as defaults from \"../../defaults\";\nimport * as artifacts from \"./artifacts\";\nimport * as util from \"../util\";\n\nexport const remoteLocationSchema = z.object({\n registry: z.string().describe(\"name of the registry to use for package download\"),\n package: z\n .string()\n .describe(\"full package path in registry, e.g. 'common/jdk/21.0.2.13.1-{os}-{arch}.tgz\"),\n});\n\nexport const assetSchema = z.object({\n ...remoteLocationSchema.shape,\n url: z.string().describe(\"asset download URL\"),\n});\nexport type assetInfo = z.infer<typeof assetSchema>;\n\nexport const dockerSchema = z.object({\n tag: z.string().describe(\"full image tag to pull on backend side to execute this software\"),\n entrypoint: z.array(z.string()).describe(\"override image's entrypoint\"),\n cmd: z.array(z.string()).describe(\"command to be run in the container\"),\n\n pkg: z\n .string()\n .default(defaults.DOCKER_PLACEHOLDER_PKG)\n .describe(\n 'what to substitute in place of \"{pkg}\" variable in \"cmd\" (for artifacts with docker autogeneration)',\n ),\n});\nexport type dockerInfo = z.infer<typeof dockerSchema>;\n\nexport const runEnvironmentSchema = z.object({\n type: z.enum(artifacts.runEnvironmentTypes),\n ...remoteLocationSchema.shape,\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.string(),\n});\nexport type runEnvInfo = z.infer<typeof runEnvironmentSchema>;\n\nexport const runDependencyJavaSchema = runEnvironmentSchema.extend({\n type: z.literal(\"java\"),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyJava = z.infer<typeof runDependencyJavaSchema>;\n\nexport const runDependencyPythonSchema = runEnvironmentSchema.extend({\n type: z.literal(\"python\"),\n [\"python-version\"]: z.string(),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyPython = z.infer<typeof runDependencyPythonSchema>;\n\nexport const runDependencyRSchema = runEnvironmentSchema.extend({\n type: z.literal(\"R\"),\n [\"r-version\"]: z.string(),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyR = z.infer<typeof runDependencyRSchema>;\n\nexport type runEnvDependency = runEnvDependencyJava | runEnvDependencyPython | runEnvDependencyR;\n\nexport const commonPackageSettingsSchema = z.object({\n cmd: z.array(z.string()).min(1).describe(\"run given command, appended by args from workflow\"),\n\n envVars: z\n .array(\n z\n .string()\n .regex(\n /=/,\n \"full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes\",\n ),\n )\n .optional(),\n});\n\nexport const binaryPackageSchema = z.object({\n type: z.literal(\"binary\"),\n ...commonPackageSettingsSchema.shape,\n\n pkg: z\n .string()\n .optional()\n .describe(\"location of all package contents in Docker container (default: /app)\"),\n});\n\nexport const javaPackageSettingsSchema = z.object({\n type: z.literal(\"java\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyJavaSchema,\n});\n\nexport const pythonPackageSettingsSchema = z.object({\n type: z.literal(\"python\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyPythonSchema,\n\n toolset: z.string(),\n dependencies: z\n .record(z.string(), z.string())\n .describe(\n \"paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'\",\n ),\n});\n\nexport const rPackageSettingsSchema = z.object({\n type: z.literal(\"R\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyRSchema,\n\n toolset: z.string(),\n dependencies: z\n .record(z.string(), z.string())\n .describe(\n \"paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'\",\n ),\n});\n\nexport const condaPackageSchema = z.object({\n type: z.literal(\"conda\"),\n ...commonPackageSettingsSchema.shape,\n\n [\"micromamba-version\"]: z\n .string()\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 .describe(\"location of spec.yaml describing conda environment, relative to package root.\"),\n});\n\nexport const remoteSoftwareSchema = z.union([\n remoteLocationSchema.extend(binaryPackageSchema.shape),\n remoteLocationSchema.extend(javaPackageSettingsSchema.shape),\n remoteLocationSchema.extend(pythonPackageSettingsSchema.shape),\n remoteLocationSchema.extend(rPackageSettingsSchema.shape),\n remoteLocationSchema.extend(condaPackageSchema.shape),\n]);\nexport type remoteSoftwareType = z.infer<typeof remoteSoftwareSchema>;\n\nexport const localLocationSchema = z.object({\n hash: z\n .string()\n .describe(\n \"hash of software directory. Makes deduplication to work properly when you actively develop software\",\n ),\n path: z.string().describe(\"absolute path to root directory of software on local host\"),\n});\n\nexport const localSoftwareSchema = z.discriminatedUnion(\"type\", [\n localLocationSchema.extend(binaryPackageSchema.shape),\n localLocationSchema.extend(javaPackageSettingsSchema.shape),\n localLocationSchema.extend(pythonPackageSettingsSchema.shape),\n localLocationSchema.extend(rPackageSettingsSchema.shape),\n localLocationSchema.extend(condaPackageSchema.shape),\n // Docker can be used 'as usual' without any special 'local' section magic\n]);\nexport type localSoftwareType = z.infer<typeof localSoftwareSchema>;\n\n// Full .sw.json file schema\nexport const swJsonSchema = z\n .object({\n isDev: z.boolean().optional(),\n\n asset: assetSchema.optional(),\n binary: remoteSoftwareSchema.optional(),\n docker: dockerSchema.optional(),\n runEnv: runEnvironmentSchema.optional(),\n local: localSoftwareSchema.optional(),\n })\n .refine(\n (data) =>\n util.toInt(data.runEnv) +\n util.toInt(data.binary || data.docker) + // allow both docker and binary to be set in single entrypoint\n util.toInt(data.asset) +\n util.toInt(data.local) ==\n 1,\n {\n message:\n \"entrypoint cannot point to several packages at once: choose 'environment', 'binary', 'asset', 'conda' or 'local'\",\n path: [\"environment | binary | asset | conda | local\"],\n },\n );\n\nexport type swJsonType = z.infer<typeof swJsonSchema> & {\n id: util.artifactID;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { CONDA_DATA_LOCATION, DOCKER_PLACEHOLDER_PKG } from "../../defaults.js";
|
|
2
|
+
import { toInt } from "../util.js";
|
|
3
|
+
import { runEnvironmentTypes } from "./artifacts.js";
|
|
4
|
+
import { z } from "zod/v4";
|
|
5
|
+
//#region src/core/schemas/sw-json.ts
|
|
6
|
+
const remoteLocationSchema = z.object({
|
|
7
|
+
registry: z.string().describe("name of the registry to use for package download"),
|
|
8
|
+
package: z.string().describe("full package path in registry, e.g. 'common/jdk/21.0.2.13.1-{os}-{arch}.tgz")
|
|
9
|
+
});
|
|
10
|
+
const assetSchema = z.object({
|
|
11
|
+
...remoteLocationSchema.shape,
|
|
12
|
+
url: z.string().describe("asset download URL")
|
|
13
|
+
});
|
|
14
|
+
const dockerSchema = z.object({
|
|
15
|
+
tag: z.string().describe("full image tag to pull on backend side to execute this software"),
|
|
16
|
+
entrypoint: z.array(z.string()).describe("override image's entrypoint"),
|
|
17
|
+
cmd: z.array(z.string()).describe("command to be run in the container"),
|
|
18
|
+
pkg: z.string().default(DOCKER_PLACEHOLDER_PKG).describe("what to substitute in place of \"{pkg}\" variable in \"cmd\" (for artifacts with docker autogeneration)")
|
|
19
|
+
});
|
|
20
|
+
const runEnvironmentSchema = z.object({
|
|
21
|
+
type: z.enum(runEnvironmentTypes),
|
|
22
|
+
...remoteLocationSchema.shape,
|
|
23
|
+
["r-version"]: z.string().optional(),
|
|
24
|
+
["python-version"]: z.string().optional(),
|
|
25
|
+
["java-version"]: z.string().optional(),
|
|
26
|
+
envVars: z.array(z.string().regex(/=/, "environment variable should be specified in format: <var-name>=<var-value>, i.e.: MY_ENV=value")).optional(),
|
|
27
|
+
binDir: z.string()
|
|
28
|
+
});
|
|
29
|
+
const runDependencyJavaSchema = runEnvironmentSchema.extend({
|
|
30
|
+
type: z.literal("java"),
|
|
31
|
+
name: z.string().describe("name used to import this package as software dependency of tengo script")
|
|
32
|
+
});
|
|
33
|
+
const runDependencyPythonSchema = runEnvironmentSchema.extend({
|
|
34
|
+
type: z.literal("python"),
|
|
35
|
+
["python-version"]: z.string(),
|
|
36
|
+
name: z.string().describe("name used to import this package as software dependency of tengo script")
|
|
37
|
+
});
|
|
38
|
+
const runDependencyRSchema = runEnvironmentSchema.extend({
|
|
39
|
+
type: z.literal("R"),
|
|
40
|
+
["r-version"]: z.string(),
|
|
41
|
+
name: z.string().describe("name used to import this package as software dependency of tengo script")
|
|
42
|
+
});
|
|
43
|
+
const commonPackageSettingsSchema = z.object({
|
|
44
|
+
cmd: z.array(z.string()).min(1).describe("run given command, appended by args from workflow"),
|
|
45
|
+
envVars: z.array(z.string().regex(/=/, "full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes")).optional()
|
|
46
|
+
});
|
|
47
|
+
const binaryPackageSchema = z.object({
|
|
48
|
+
type: z.literal("binary"),
|
|
49
|
+
...commonPackageSettingsSchema.shape,
|
|
50
|
+
pkg: z.string().optional().describe("location of all package contents in Docker container (default: /app)")
|
|
51
|
+
});
|
|
52
|
+
const javaPackageSettingsSchema = z.object({
|
|
53
|
+
type: z.literal("java"),
|
|
54
|
+
...commonPackageSettingsSchema.shape,
|
|
55
|
+
runEnv: runDependencyJavaSchema
|
|
56
|
+
});
|
|
57
|
+
const pythonPackageSettingsSchema = z.object({
|
|
58
|
+
type: z.literal("python"),
|
|
59
|
+
...commonPackageSettingsSchema.shape,
|
|
60
|
+
runEnv: runDependencyPythonSchema,
|
|
61
|
+
toolset: z.string(),
|
|
62
|
+
dependencies: z.record(z.string(), z.string()).describe("paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'")
|
|
63
|
+
});
|
|
64
|
+
const rPackageSettingsSchema = z.object({
|
|
65
|
+
type: z.literal("R"),
|
|
66
|
+
...commonPackageSettingsSchema.shape,
|
|
67
|
+
runEnv: runDependencyRSchema,
|
|
68
|
+
toolset: z.string(),
|
|
69
|
+
dependencies: z.record(z.string(), z.string()).describe("paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'")
|
|
70
|
+
});
|
|
71
|
+
const condaPackageSchema = z.object({
|
|
72
|
+
type: z.literal("conda"),
|
|
73
|
+
...commonPackageSettingsSchema.shape,
|
|
74
|
+
["micromamba-version"]: z.string().describe("version of micromamba to be used to operate with conda environments"),
|
|
75
|
+
["conda-root-dir"]: z.string().default(CONDA_DATA_LOCATION).describe("root directory of conda environment inside package root"),
|
|
76
|
+
spec: z.string().describe("location of spec.yaml describing conda environment, relative to package root.")
|
|
77
|
+
});
|
|
78
|
+
const remoteSoftwareSchema = z.union([
|
|
79
|
+
remoteLocationSchema.extend(binaryPackageSchema.shape),
|
|
80
|
+
remoteLocationSchema.extend(javaPackageSettingsSchema.shape),
|
|
81
|
+
remoteLocationSchema.extend(pythonPackageSettingsSchema.shape),
|
|
82
|
+
remoteLocationSchema.extend(rPackageSettingsSchema.shape),
|
|
83
|
+
remoteLocationSchema.extend(condaPackageSchema.shape)
|
|
84
|
+
]);
|
|
85
|
+
const localLocationSchema = z.object({
|
|
86
|
+
hash: z.string().describe("hash of software directory. Makes deduplication to work properly when you actively develop software"),
|
|
87
|
+
path: z.string().describe("absolute path to root directory of software on local host")
|
|
88
|
+
});
|
|
89
|
+
const localSoftwareSchema = z.discriminatedUnion("type", [
|
|
90
|
+
localLocationSchema.extend(binaryPackageSchema.shape),
|
|
91
|
+
localLocationSchema.extend(javaPackageSettingsSchema.shape),
|
|
92
|
+
localLocationSchema.extend(pythonPackageSettingsSchema.shape),
|
|
93
|
+
localLocationSchema.extend(rPackageSettingsSchema.shape),
|
|
94
|
+
localLocationSchema.extend(condaPackageSchema.shape)
|
|
95
|
+
]);
|
|
96
|
+
const swJsonSchema = z.object({
|
|
97
|
+
isDev: z.boolean().optional(),
|
|
98
|
+
asset: assetSchema.optional(),
|
|
99
|
+
binary: remoteSoftwareSchema.optional(),
|
|
100
|
+
docker: dockerSchema.optional(),
|
|
101
|
+
runEnv: runEnvironmentSchema.optional(),
|
|
102
|
+
local: localSoftwareSchema.optional()
|
|
103
|
+
}).refine((data) => toInt(data.runEnv) + toInt(data.binary || data.docker) + toInt(data.asset) + toInt(data.local) == 1, {
|
|
104
|
+
message: "entrypoint cannot point to several packages at once: choose 'environment', 'binary', 'asset', 'conda' or 'local'",
|
|
105
|
+
path: ["environment | binary | asset | conda | local"]
|
|
106
|
+
});
|
|
107
|
+
//#endregion
|
|
108
|
+
export { swJsonSchema };
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=sw-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw-json.js","names":["defaults.DOCKER_PLACEHOLDER_PKG","artifacts.runEnvironmentTypes","defaults.CONDA_DATA_LOCATION","util.toInt"],"sources":["../../../src/core/schemas/sw-json.ts"],"sourcesContent":["import { z } from \"zod/v4\";\nimport * as defaults from \"../../defaults\";\nimport * as artifacts from \"./artifacts\";\nimport * as util from \"../util\";\n\nexport const remoteLocationSchema = z.object({\n registry: z.string().describe(\"name of the registry to use for package download\"),\n package: z\n .string()\n .describe(\"full package path in registry, e.g. 'common/jdk/21.0.2.13.1-{os}-{arch}.tgz\"),\n});\n\nexport const assetSchema = z.object({\n ...remoteLocationSchema.shape,\n url: z.string().describe(\"asset download URL\"),\n});\nexport type assetInfo = z.infer<typeof assetSchema>;\n\nexport const dockerSchema = z.object({\n tag: z.string().describe(\"full image tag to pull on backend side to execute this software\"),\n entrypoint: z.array(z.string()).describe(\"override image's entrypoint\"),\n cmd: z.array(z.string()).describe(\"command to be run in the container\"),\n\n pkg: z\n .string()\n .default(defaults.DOCKER_PLACEHOLDER_PKG)\n .describe(\n 'what to substitute in place of \"{pkg}\" variable in \"cmd\" (for artifacts with docker autogeneration)',\n ),\n});\nexport type dockerInfo = z.infer<typeof dockerSchema>;\n\nexport const runEnvironmentSchema = z.object({\n type: z.enum(artifacts.runEnvironmentTypes),\n ...remoteLocationSchema.shape,\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.string(),\n});\nexport type runEnvInfo = z.infer<typeof runEnvironmentSchema>;\n\nexport const runDependencyJavaSchema = runEnvironmentSchema.extend({\n type: z.literal(\"java\"),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyJava = z.infer<typeof runDependencyJavaSchema>;\n\nexport const runDependencyPythonSchema = runEnvironmentSchema.extend({\n type: z.literal(\"python\"),\n [\"python-version\"]: z.string(),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyPython = z.infer<typeof runDependencyPythonSchema>;\n\nexport const runDependencyRSchema = runEnvironmentSchema.extend({\n type: z.literal(\"R\"),\n [\"r-version\"]: z.string(),\n name: z\n .string()\n .describe(\"name used to import this package as software dependency of tengo script\"),\n});\nexport type runEnvDependencyR = z.infer<typeof runDependencyRSchema>;\n\nexport type runEnvDependency = runEnvDependencyJava | runEnvDependencyPython | runEnvDependencyR;\n\nexport const commonPackageSettingsSchema = z.object({\n cmd: z.array(z.string()).min(1).describe(\"run given command, appended by args from workflow\"),\n\n envVars: z\n .array(\n z\n .string()\n .regex(\n /=/,\n \"full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes\",\n ),\n )\n .optional(),\n});\n\nexport const binaryPackageSchema = z.object({\n type: z.literal(\"binary\"),\n ...commonPackageSettingsSchema.shape,\n\n pkg: z\n .string()\n .optional()\n .describe(\"location of all package contents in Docker container (default: /app)\"),\n});\n\nexport const javaPackageSettingsSchema = z.object({\n type: z.literal(\"java\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyJavaSchema,\n});\n\nexport const pythonPackageSettingsSchema = z.object({\n type: z.literal(\"python\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyPythonSchema,\n\n toolset: z.string(),\n dependencies: z\n .record(z.string(), z.string())\n .describe(\n \"paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'\",\n ),\n});\n\nexport const rPackageSettingsSchema = z.object({\n type: z.literal(\"R\"),\n\n ...commonPackageSettingsSchema.shape,\n runEnv: runDependencyRSchema,\n\n toolset: z.string(),\n dependencies: z\n .record(z.string(), z.string())\n .describe(\n \"paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'\",\n ),\n});\n\nexport const condaPackageSchema = z.object({\n type: z.literal(\"conda\"),\n ...commonPackageSettingsSchema.shape,\n\n [\"micromamba-version\"]: z\n .string()\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 .describe(\"location of spec.yaml describing conda environment, relative to package root.\"),\n});\n\nexport const remoteSoftwareSchema = z.union([\n remoteLocationSchema.extend(binaryPackageSchema.shape),\n remoteLocationSchema.extend(javaPackageSettingsSchema.shape),\n remoteLocationSchema.extend(pythonPackageSettingsSchema.shape),\n remoteLocationSchema.extend(rPackageSettingsSchema.shape),\n remoteLocationSchema.extend(condaPackageSchema.shape),\n]);\nexport type remoteSoftwareType = z.infer<typeof remoteSoftwareSchema>;\n\nexport const localLocationSchema = z.object({\n hash: z\n .string()\n .describe(\n \"hash of software directory. Makes deduplication to work properly when you actively develop software\",\n ),\n path: z.string().describe(\"absolute path to root directory of software on local host\"),\n});\n\nexport const localSoftwareSchema = z.discriminatedUnion(\"type\", [\n localLocationSchema.extend(binaryPackageSchema.shape),\n localLocationSchema.extend(javaPackageSettingsSchema.shape),\n localLocationSchema.extend(pythonPackageSettingsSchema.shape),\n localLocationSchema.extend(rPackageSettingsSchema.shape),\n localLocationSchema.extend(condaPackageSchema.shape),\n // Docker can be used 'as usual' without any special 'local' section magic\n]);\nexport type localSoftwareType = z.infer<typeof localSoftwareSchema>;\n\n// Full .sw.json file schema\nexport const swJsonSchema = z\n .object({\n isDev: z.boolean().optional(),\n\n asset: assetSchema.optional(),\n binary: remoteSoftwareSchema.optional(),\n docker: dockerSchema.optional(),\n runEnv: runEnvironmentSchema.optional(),\n local: localSoftwareSchema.optional(),\n })\n .refine(\n (data) =>\n util.toInt(data.runEnv) +\n util.toInt(data.binary || data.docker) + // allow both docker and binary to be set in single entrypoint\n util.toInt(data.asset) +\n util.toInt(data.local) ==\n 1,\n {\n message:\n \"entrypoint cannot point to several packages at once: choose 'environment', 'binary', 'asset', 'conda' or 'local'\",\n path: [\"environment | binary | asset | conda | local\"],\n },\n );\n\nexport type swJsonType = z.infer<typeof swJsonSchema> & {\n id: util.artifactID;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_util = require("./util.cjs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
node_path = require_runtime.__toESM(node_path);
|
|
5
|
+
let node_path_posix = require("node:path/posix");
|
|
6
|
+
node_path_posix = require_runtime.__toESM(node_path_posix);
|
|
7
|
+
let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
|
|
8
|
+
let _aws_sdk_lib_storage = require("@aws-sdk/lib-storage");
|
|
9
|
+
//#region src/core/storage.ts
|
|
10
|
+
async function objectExists(client, bucket, key) {
|
|
11
|
+
try {
|
|
12
|
+
await client.headObject({
|
|
13
|
+
Bucket: bucket,
|
|
14
|
+
Key: key
|
|
15
|
+
});
|
|
16
|
+
return true;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof Error && error.name === "NotFound") return false;
|
|
19
|
+
throw require_util.wrapErr(error, `failed to check if object exists in S3 bucket ${bucket}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function newS3(options, bucket) {
|
|
23
|
+
const client = new _aws_sdk_client_s3.S3(options);
|
|
24
|
+
try {
|
|
25
|
+
await objectExists(client, bucket, "/");
|
|
26
|
+
} catch (error) {
|
|
27
|
+
throw require_util.CLIError(`credentials given to package builder do not have access to S3 bucket '${bucket}': ${error}`);
|
|
28
|
+
}
|
|
29
|
+
return client;
|
|
30
|
+
}
|
|
31
|
+
var S3Storage = class {
|
|
32
|
+
constructor(client, bucket, root = "") {
|
|
33
|
+
this.client = client;
|
|
34
|
+
this.bucket = bucket;
|
|
35
|
+
this.root = root;
|
|
36
|
+
}
|
|
37
|
+
async exists(file) {
|
|
38
|
+
return objectExists(this.client, this.bucket, node_path_posix.default.join(this.root, file));
|
|
39
|
+
}
|
|
40
|
+
async putFile(file, data) {
|
|
41
|
+
try {
|
|
42
|
+
await new _aws_sdk_lib_storage.Upload({
|
|
43
|
+
client: this.client,
|
|
44
|
+
params: {
|
|
45
|
+
Bucket: this.bucket,
|
|
46
|
+
Key: node_path_posix.default.join(this.root, file),
|
|
47
|
+
Body: data
|
|
48
|
+
}
|
|
49
|
+
}).done();
|
|
50
|
+
} catch (e) {
|
|
51
|
+
throw require_util.wrapErr(e, `failed to put object into S3 bucket ${this.bucket}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
async function initByUrl(address, pkgRoot) {
|
|
56
|
+
if (address === "") throw require_util.CLIError(`Empty registry storage address`);
|
|
57
|
+
try {
|
|
58
|
+
const url = new URL(address, `file:${pkgRoot.split(node_path.default.sep).join(node_path_posix.default.sep)}/`);
|
|
59
|
+
switch (url.protocol) {
|
|
60
|
+
case "s3:": {
|
|
61
|
+
const s3Options = {};
|
|
62
|
+
const s3Region = url.searchParams.get("region");
|
|
63
|
+
if (s3Region) s3Options.region = s3Region;
|
|
64
|
+
const s3Bucket = url.hostname;
|
|
65
|
+
const s3KeyPrefix = require_util.trimPrefix(url.pathname, "/");
|
|
66
|
+
return new S3Storage(await newS3(s3Options, s3Bucket), s3Bucket, s3KeyPrefix);
|
|
67
|
+
}
|
|
68
|
+
case "s3e:": {
|
|
69
|
+
const s3eOptions = {};
|
|
70
|
+
const s3eRegion = url.searchParams.get("region");
|
|
71
|
+
if (s3eRegion) s3eOptions.region = s3eRegion;
|
|
72
|
+
const s3ePath = url.pathname.split("/").slice(1);
|
|
73
|
+
const s3eBucket = s3ePath[0];
|
|
74
|
+
const s3eKeyPrefix = s3ePath.length > 1 ? require_util.trimPrefix(s3ePath[1], "/") : "";
|
|
75
|
+
return new S3Storage(await newS3(s3eOptions, s3eBucket), s3eBucket, s3eKeyPrefix);
|
|
76
|
+
}
|
|
77
|
+
default: throw require_util.CLIError(`Protocol ${url.protocol} is not supported for software registries yet. Use your own tooling for package upload`);
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {
|
|
80
|
+
throw require_util.wrapErr(e, `failed to init storage driver from URL`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
exports.initByUrl = initByUrl;
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.cjs","names":["S3","pathPosix","Upload","path"],"sources":["../../src/core/storage.ts"],"sourcesContent":["import pathPosix from \"node:path/posix\";\nimport { S3 } from \"@aws-sdk/client-s3\";\nimport { Upload } from \"@aws-sdk/lib-storage\";\nimport path from \"node:path\";\nimport * as util from \"./util\";\nimport type { Readable } from \"node:stream\";\n\nexport const supportedTypes = [\"S3\"] as const; // add other types when we support them\nexport type storageType = (typeof supportedTypes)[number];\n\nexport function typeToURLScheme(sType: storageType): string {\n switch (sType) {\n case \"S3\":\n return \"s3\";\n default:\n util.assertNever(sType);\n throw new Error(\"no schema defined for storage type\"); // just to calm down TS type analyzer\n }\n}\n\nexport interface RegistryStorage {\n exists(file: string): Promise<boolean>;\n putFile(file: string, data: Buffer | Readable): Promise<void>;\n}\n\nasync function objectExists(client: S3, bucket: string, key: string): Promise<boolean> {\n try {\n await client.headObject({\n Bucket: bucket,\n Key: key,\n });\n\n return true;\n } catch (error) {\n if (error instanceof Error && error.name === \"NotFound\") {\n return false;\n }\n\n throw util.wrapErr(error, `failed to check if object exists in S3 bucket ${bucket}`);\n }\n}\n\nasync function newS3(\n options: NonNullable<ConstructorParameters<typeof S3>[0]>,\n bucket: string,\n): Promise<S3> {\n const client = new S3(options);\n\n try {\n await objectExists(client, bucket, \"/\");\n } catch (error) {\n throw util.CLIError(\n `credentials given to package builder do not have access to S3 bucket '${bucket}': ${error}`,\n );\n }\n\n return client;\n}\n\nexport class S3Storage implements RegistryStorage {\n constructor(\n public readonly client: S3,\n public readonly bucket: string,\n public readonly root: string = \"\",\n ) {}\n\n async exists(file: string): Promise<boolean> {\n return objectExists(this.client, this.bucket, pathPosix.join(this.root, file));\n }\n\n async putFile(file: string, data: Buffer | Readable): Promise<void> {\n try {\n const upload = new Upload({\n client: this.client,\n params: {\n Bucket: this.bucket,\n Key: pathPosix.join(this.root, file),\n Body: data,\n },\n });\n\n await upload.done();\n } catch (e) {\n throw util.wrapErr(e, `failed to put object into S3 bucket ${this.bucket}`);\n }\n }\n}\n\nexport async function initByUrl(address: string, pkgRoot: string): Promise<RegistryStorage> {\n if (address === \"\") {\n throw util.CLIError(`Empty registry storage address`);\n }\n\n try {\n const url = new URL(address, `file:${pkgRoot.split(path.sep).join(pathPosix.sep)}/`);\n switch (url.protocol) {\n case \"s3:\": {\n const s3Options: NonNullable<ConstructorParameters<typeof S3>[0]> = {};\n const s3Region = url.searchParams.get(\"region\");\n if (s3Region) s3Options.region = s3Region;\n const s3Bucket = url.hostname;\n const s3KeyPrefix = util.trimPrefix(url.pathname, \"/\");\n const s3Client = await newS3(s3Options, s3Bucket);\n return new S3Storage(s3Client, s3Bucket, s3KeyPrefix);\n }\n case \"s3e:\": {\n const s3eOptions: NonNullable<ConstructorParameters<typeof S3>[0]> = {};\n const s3eRegion = url.searchParams.get(\"region\");\n if (s3eRegion) s3eOptions.region = s3eRegion;\n\n const s3ePath = url.pathname.split(\"/\").slice(1); // '/bucket/keyPrefix' -> ['', 'bucket', 'keyPrefix'] -> ['bucket', 'keyPrefix']\n const s3eBucket = s3ePath[0];\n const s3eKeyPrefix = s3ePath.length > 1 ? util.trimPrefix(s3ePath[1], \"/\") : \"\";\n const s3eClient = await newS3(s3eOptions, s3eBucket);\n return new S3Storage(s3eClient, s3eBucket, s3eKeyPrefix);\n }\n default:\n throw util.CLIError(\n `Protocol ${url.protocol} is not supported for software registries yet. Use your own tooling for package upload`,\n );\n }\n } catch (e) {\n throw util.wrapErr(e, `failed to init storage driver from URL`);\n }\n}\n"],"mappings":";;;;;;;;;AAyBA,eAAe,aAAa,QAAY,QAAgB,KAA+B;AACrF,KAAI;AACF,QAAM,OAAO,WAAW;GACtB,QAAQ;GACR,KAAK;GACN,CAAC;AAEF,SAAO;UACA,OAAO;AACd,MAAI,iBAAiB,SAAS,MAAM,SAAS,WAC3C,QAAO;AAGT,QAAA,aAAA,QAAmB,OAAO,iDAAiD,SAAS;;;AAIxF,eAAe,MACb,SACA,QACa;CACb,MAAM,SAAS,IAAIA,mBAAAA,GAAG,QAAQ;AAE9B,KAAI;AACF,QAAM,aAAa,QAAQ,QAAQ,IAAI;UAChC,OAAO;AACd,QAAA,aAAA,SACE,yEAAyE,OAAO,KAAK,QACtF;;AAGH,QAAO;;AAGT,IAAa,YAAb,MAAkD;CAChD,YACE,QACA,QACA,OAA+B,IAC/B;AAHgB,OAAA,SAAA;AACA,OAAA,SAAA;AACA,OAAA,OAAA;;CAGlB,MAAM,OAAO,MAAgC;AAC3C,SAAO,aAAa,KAAK,QAAQ,KAAK,QAAQC,gBAAAA,QAAU,KAAK,KAAK,MAAM,KAAK,CAAC;;CAGhF,MAAM,QAAQ,MAAc,MAAwC;AAClE,MAAI;AAUF,SATe,IAAIC,qBAAAA,OAAO;IACxB,QAAQ,KAAK;IACb,QAAQ;KACN,QAAQ,KAAK;KACb,KAAKD,gBAAAA,QAAU,KAAK,KAAK,MAAM,KAAK;KACpC,MAAM;KACP;IACF,CAAC,CAEW,MAAM;WACZ,GAAG;AACV,SAAA,aAAA,QAAmB,GAAG,uCAAuC,KAAK,SAAS;;;;AAKjF,eAAsB,UAAU,SAAiB,SAA2C;AAC1F,KAAI,YAAY,GACd,OAAA,aAAA,SAAoB,iCAAiC;AAGvD,KAAI;EACF,MAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,QAAQ,MAAME,UAAAA,QAAK,IAAI,CAAC,KAAKF,gBAAAA,QAAU,IAAI,CAAC,GAAG;AACpF,UAAQ,IAAI,UAAZ;GACE,KAAK,OAAO;IACV,MAAM,YAA8D,EAAE;IACtE,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS;AAC/C,QAAI,SAAU,WAAU,SAAS;IACjC,MAAM,WAAW,IAAI;IACrB,MAAM,cAAA,aAAA,WAA8B,IAAI,UAAU,IAAI;AAEtD,WAAO,IAAI,UADM,MAAM,MAAM,WAAW,SAAS,EAClB,UAAU,YAAY;;GAEvD,KAAK,QAAQ;IACX,MAAM,aAA+D,EAAE;IACvE,MAAM,YAAY,IAAI,aAAa,IAAI,SAAS;AAChD,QAAI,UAAW,YAAW,SAAS;IAEnC,MAAM,UAAU,IAAI,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE;IAChD,MAAM,YAAY,QAAQ;IAC1B,MAAM,eAAe,QAAQ,SAAS,IAAA,aAAA,WAAoB,QAAQ,IAAI,IAAI,GAAG;AAE7E,WAAO,IAAI,UADO,MAAM,MAAM,YAAY,UAAU,EACpB,WAAW,aAAa;;GAE1D,QACE,OAAA,aAAA,SACE,YAAY,IAAI,SAAS,wFAC1B;;UAEE,GAAG;AACV,QAAA,aAAA,QAAmB,GAAG,yCAAyC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { CLIError, trimPrefix, wrapErr } from "./util.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pathPosix from "node:path/posix";
|
|
4
|
+
import { S3 } from "@aws-sdk/client-s3";
|
|
5
|
+
import { Upload } from "@aws-sdk/lib-storage";
|
|
6
|
+
//#region src/core/storage.ts
|
|
7
|
+
async function objectExists(client, bucket, key) {
|
|
8
|
+
try {
|
|
9
|
+
await client.headObject({
|
|
10
|
+
Bucket: bucket,
|
|
11
|
+
Key: key
|
|
12
|
+
});
|
|
13
|
+
return true;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (error instanceof Error && error.name === "NotFound") return false;
|
|
16
|
+
throw wrapErr(error, `failed to check if object exists in S3 bucket ${bucket}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function newS3(options, bucket) {
|
|
20
|
+
const client = new S3(options);
|
|
21
|
+
try {
|
|
22
|
+
await objectExists(client, bucket, "/");
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw CLIError(`credentials given to package builder do not have access to S3 bucket '${bucket}': ${error}`);
|
|
25
|
+
}
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
var S3Storage = class {
|
|
29
|
+
constructor(client, bucket, root = "") {
|
|
30
|
+
this.client = client;
|
|
31
|
+
this.bucket = bucket;
|
|
32
|
+
this.root = root;
|
|
33
|
+
}
|
|
34
|
+
async exists(file) {
|
|
35
|
+
return objectExists(this.client, this.bucket, pathPosix.join(this.root, file));
|
|
36
|
+
}
|
|
37
|
+
async putFile(file, data) {
|
|
38
|
+
try {
|
|
39
|
+
await new Upload({
|
|
40
|
+
client: this.client,
|
|
41
|
+
params: {
|
|
42
|
+
Bucket: this.bucket,
|
|
43
|
+
Key: pathPosix.join(this.root, file),
|
|
44
|
+
Body: data
|
|
45
|
+
}
|
|
46
|
+
}).done();
|
|
47
|
+
} catch (e) {
|
|
48
|
+
throw wrapErr(e, `failed to put object into S3 bucket ${this.bucket}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
async function initByUrl(address, pkgRoot) {
|
|
53
|
+
if (address === "") throw CLIError(`Empty registry storage address`);
|
|
54
|
+
try {
|
|
55
|
+
const url = new URL(address, `file:${pkgRoot.split(path.sep).join(pathPosix.sep)}/`);
|
|
56
|
+
switch (url.protocol) {
|
|
57
|
+
case "s3:": {
|
|
58
|
+
const s3Options = {};
|
|
59
|
+
const s3Region = url.searchParams.get("region");
|
|
60
|
+
if (s3Region) s3Options.region = s3Region;
|
|
61
|
+
const s3Bucket = url.hostname;
|
|
62
|
+
const s3KeyPrefix = trimPrefix(url.pathname, "/");
|
|
63
|
+
return new S3Storage(await newS3(s3Options, s3Bucket), s3Bucket, s3KeyPrefix);
|
|
64
|
+
}
|
|
65
|
+
case "s3e:": {
|
|
66
|
+
const s3eOptions = {};
|
|
67
|
+
const s3eRegion = url.searchParams.get("region");
|
|
68
|
+
if (s3eRegion) s3eOptions.region = s3eRegion;
|
|
69
|
+
const s3ePath = url.pathname.split("/").slice(1);
|
|
70
|
+
const s3eBucket = s3ePath[0];
|
|
71
|
+
const s3eKeyPrefix = s3ePath.length > 1 ? trimPrefix(s3ePath[1], "/") : "";
|
|
72
|
+
return new S3Storage(await newS3(s3eOptions, s3eBucket), s3eBucket, s3eKeyPrefix);
|
|
73
|
+
}
|
|
74
|
+
default: throw CLIError(`Protocol ${url.protocol} is not supported for software registries yet. Use your own tooling for package upload`);
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw wrapErr(e, `failed to init storage driver from URL`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { initByUrl };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","names":["util.wrapErr","util.CLIError","util.trimPrefix"],"sources":["../../src/core/storage.ts"],"sourcesContent":["import pathPosix from \"node:path/posix\";\nimport { S3 } from \"@aws-sdk/client-s3\";\nimport { Upload } from \"@aws-sdk/lib-storage\";\nimport path from \"node:path\";\nimport * as util from \"./util\";\nimport type { Readable } from \"node:stream\";\n\nexport const supportedTypes = [\"S3\"] as const; // add other types when we support them\nexport type storageType = (typeof supportedTypes)[number];\n\nexport function typeToURLScheme(sType: storageType): string {\n switch (sType) {\n case \"S3\":\n return \"s3\";\n default:\n util.assertNever(sType);\n throw new Error(\"no schema defined for storage type\"); // just to calm down TS type analyzer\n }\n}\n\nexport interface RegistryStorage {\n exists(file: string): Promise<boolean>;\n putFile(file: string, data: Buffer | Readable): Promise<void>;\n}\n\nasync function objectExists(client: S3, bucket: string, key: string): Promise<boolean> {\n try {\n await client.headObject({\n Bucket: bucket,\n Key: key,\n });\n\n return true;\n } catch (error) {\n if (error instanceof Error && error.name === \"NotFound\") {\n return false;\n }\n\n throw util.wrapErr(error, `failed to check if object exists in S3 bucket ${bucket}`);\n }\n}\n\nasync function newS3(\n options: NonNullable<ConstructorParameters<typeof S3>[0]>,\n bucket: string,\n): Promise<S3> {\n const client = new S3(options);\n\n try {\n await objectExists(client, bucket, \"/\");\n } catch (error) {\n throw util.CLIError(\n `credentials given to package builder do not have access to S3 bucket '${bucket}': ${error}`,\n );\n }\n\n return client;\n}\n\nexport class S3Storage implements RegistryStorage {\n constructor(\n public readonly client: S3,\n public readonly bucket: string,\n public readonly root: string = \"\",\n ) {}\n\n async exists(file: string): Promise<boolean> {\n return objectExists(this.client, this.bucket, pathPosix.join(this.root, file));\n }\n\n async putFile(file: string, data: Buffer | Readable): Promise<void> {\n try {\n const upload = new Upload({\n client: this.client,\n params: {\n Bucket: this.bucket,\n Key: pathPosix.join(this.root, file),\n Body: data,\n },\n });\n\n await upload.done();\n } catch (e) {\n throw util.wrapErr(e, `failed to put object into S3 bucket ${this.bucket}`);\n }\n }\n}\n\nexport async function initByUrl(address: string, pkgRoot: string): Promise<RegistryStorage> {\n if (address === \"\") {\n throw util.CLIError(`Empty registry storage address`);\n }\n\n try {\n const url = new URL(address, `file:${pkgRoot.split(path.sep).join(pathPosix.sep)}/`);\n switch (url.protocol) {\n case \"s3:\": {\n const s3Options: NonNullable<ConstructorParameters<typeof S3>[0]> = {};\n const s3Region = url.searchParams.get(\"region\");\n if (s3Region) s3Options.region = s3Region;\n const s3Bucket = url.hostname;\n const s3KeyPrefix = util.trimPrefix(url.pathname, \"/\");\n const s3Client = await newS3(s3Options, s3Bucket);\n return new S3Storage(s3Client, s3Bucket, s3KeyPrefix);\n }\n case \"s3e:\": {\n const s3eOptions: NonNullable<ConstructorParameters<typeof S3>[0]> = {};\n const s3eRegion = url.searchParams.get(\"region\");\n if (s3eRegion) s3eOptions.region = s3eRegion;\n\n const s3ePath = url.pathname.split(\"/\").slice(1); // '/bucket/keyPrefix' -> ['', 'bucket', 'keyPrefix'] -> ['bucket', 'keyPrefix']\n const s3eBucket = s3ePath[0];\n const s3eKeyPrefix = s3ePath.length > 1 ? util.trimPrefix(s3ePath[1], \"/\") : \"\";\n const s3eClient = await newS3(s3eOptions, s3eBucket);\n return new S3Storage(s3eClient, s3eBucket, s3eKeyPrefix);\n }\n default:\n throw util.CLIError(\n `Protocol ${url.protocol} is not supported for software registries yet. Use your own tooling for package upload`,\n );\n }\n } catch (e) {\n throw util.wrapErr(e, `failed to init storage driver from URL`);\n }\n}\n"],"mappings":";;;;;;AAyBA,eAAe,aAAa,QAAY,QAAgB,KAA+B;AACrF,KAAI;AACF,QAAM,OAAO,WAAW;GACtB,QAAQ;GACR,KAAK;GACN,CAAC;AAEF,SAAO;UACA,OAAO;AACd,MAAI,iBAAiB,SAAS,MAAM,SAAS,WAC3C,QAAO;AAGT,QAAMA,QAAa,OAAO,iDAAiD,SAAS;;;AAIxF,eAAe,MACb,SACA,QACa;CACb,MAAM,SAAS,IAAI,GAAG,QAAQ;AAE9B,KAAI;AACF,QAAM,aAAa,QAAQ,QAAQ,IAAI;UAChC,OAAO;AACd,QAAMC,SACJ,yEAAyE,OAAO,KAAK,QACtF;;AAGH,QAAO;;AAGT,IAAa,YAAb,MAAkD;CAChD,YACE,QACA,QACA,OAA+B,IAC/B;AAHgB,OAAA,SAAA;AACA,OAAA,SAAA;AACA,OAAA,OAAA;;CAGlB,MAAM,OAAO,MAAgC;AAC3C,SAAO,aAAa,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK,KAAK,MAAM,KAAK,CAAC;;CAGhF,MAAM,QAAQ,MAAc,MAAwC;AAClE,MAAI;AAUF,SATe,IAAI,OAAO;IACxB,QAAQ,KAAK;IACb,QAAQ;KACN,QAAQ,KAAK;KACb,KAAK,UAAU,KAAK,KAAK,MAAM,KAAK;KACpC,MAAM;KACP;IACF,CAAC,CAEW,MAAM;WACZ,GAAG;AACV,SAAMD,QAAa,GAAG,uCAAuC,KAAK,SAAS;;;;AAKjF,eAAsB,UAAU,SAAiB,SAA2C;AAC1F,KAAI,YAAY,GACd,OAAMC,SAAc,iCAAiC;AAGvD,KAAI;EACF,MAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,QAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,GAAG;AACpF,UAAQ,IAAI,UAAZ;GACE,KAAK,OAAO;IACV,MAAM,YAA8D,EAAE;IACtE,MAAM,WAAW,IAAI,aAAa,IAAI,SAAS;AAC/C,QAAI,SAAU,WAAU,SAAS;IACjC,MAAM,WAAW,IAAI;IACrB,MAAM,cAAcC,WAAgB,IAAI,UAAU,IAAI;AAEtD,WAAO,IAAI,UADM,MAAM,MAAM,WAAW,SAAS,EAClB,UAAU,YAAY;;GAEvD,KAAK,QAAQ;IACX,MAAM,aAA+D,EAAE;IACvE,MAAM,YAAY,IAAI,aAAa,IAAI,SAAS;AAChD,QAAI,UAAW,YAAW,SAAS;IAEnC,MAAM,UAAU,IAAI,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE;IAChD,MAAM,YAAY,QAAQ;IAC1B,MAAM,eAAe,QAAQ,SAAS,IAAIA,WAAgB,QAAQ,IAAI,IAAI,GAAG;AAE7E,WAAO,IAAI,UADO,MAAM,MAAM,YAAY,UAAU,EACpB,WAAW,aAAa;;GAE1D,QACE,OAAMD,SACJ,YAAY,IAAI,SAAS,wFAC1B;;UAEE,GAAG;AACV,QAAMD,QAAa,GAAG,yCAAyC"}
|