@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.
Files changed (134) hide show
  1. package/assets/conda-dockerfile.template +45 -0
  2. package/assets/python-dockerfile.template +22 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +33 -0
  4. package/dist/_virtual/_rolldown/runtime.js +13 -0
  5. package/dist/core/archive.cjs +52 -0
  6. package/dist/core/archive.cjs.map +1 -0
  7. package/dist/core/archive.js +47 -0
  8. package/dist/core/archive.js.map +1 -0
  9. package/dist/core/conda/builder.cjs +226 -0
  10. package/dist/core/conda/builder.cjs.map +1 -0
  11. package/dist/core/conda/builder.js +220 -0
  12. package/dist/core/conda/builder.js.map +1 -0
  13. package/dist/core/conda/validate-spec.cjs +76 -0
  14. package/dist/core/conda/validate-spec.cjs.map +1 -0
  15. package/dist/core/conda/validate-spec.js +73 -0
  16. package/dist/core/conda/validate-spec.js.map +1 -0
  17. package/dist/core/core.cjs +403 -0
  18. package/dist/core/core.cjs.map +1 -0
  19. package/dist/core/core.d.ts +82 -0
  20. package/dist/core/core.d.ts.map +1 -0
  21. package/dist/core/core.js +397 -0
  22. package/dist/core/core.js.map +1 -0
  23. package/dist/core/docker-conda.cjs +75 -0
  24. package/dist/core/docker-conda.cjs.map +1 -0
  25. package/dist/core/docker-conda.js +71 -0
  26. package/dist/core/docker-conda.js.map +1 -0
  27. package/dist/core/docker-python.cjs +147 -0
  28. package/dist/core/docker-python.cjs.map +1 -0
  29. package/dist/core/docker-python.js +144 -0
  30. package/dist/core/docker-python.js.map +1 -0
  31. package/dist/core/docker.cjs +223 -0
  32. package/dist/core/docker.cjs.map +1 -0
  33. package/dist/core/docker.js +207 -0
  34. package/dist/core/docker.js.map +1 -0
  35. package/dist/core/envs.cjs +58 -0
  36. package/dist/core/envs.cjs.map +1 -0
  37. package/dist/core/envs.d.ts +26 -0
  38. package/dist/core/envs.d.ts.map +1 -0
  39. package/dist/core/envs.js +51 -0
  40. package/dist/core/envs.js.map +1 -0
  41. package/dist/core/package-info.cjs +450 -0
  42. package/dist/core/package-info.cjs.map +1 -0
  43. package/dist/core/package-info.d.ts +57 -0
  44. package/dist/core/package-info.d.ts.map +1 -0
  45. package/dist/core/package-info.js +447 -0
  46. package/dist/core/package-info.js.map +1 -0
  47. package/dist/core/paths.cjs +15 -0
  48. package/dist/core/paths.cjs.map +1 -0
  49. package/dist/core/paths.js +14 -0
  50. package/dist/core/paths.js.map +1 -0
  51. package/dist/core/resolver.cjs +99 -0
  52. package/dist/core/resolver.cjs.map +1 -0
  53. package/dist/core/resolver.js +95 -0
  54. package/dist/core/resolver.js.map +1 -0
  55. package/dist/core/schemas/artifacts.cjs +136 -0
  56. package/dist/core/schemas/artifacts.cjs.map +1 -0
  57. package/dist/core/schemas/artifacts.d.ts +280 -0
  58. package/dist/core/schemas/artifacts.d.ts.map +1 -0
  59. package/dist/core/schemas/artifacts.js +122 -0
  60. package/dist/core/schemas/artifacts.js.map +1 -0
  61. package/dist/core/schemas/entrypoints.cjs +43 -0
  62. package/dist/core/schemas/entrypoints.cjs.map +1 -0
  63. package/dist/core/schemas/entrypoints.d.ts +32 -0
  64. package/dist/core/schemas/entrypoints.d.ts.map +1 -0
  65. package/dist/core/schemas/entrypoints.js +41 -0
  66. package/dist/core/schemas/entrypoints.js.map +1 -0
  67. package/dist/core/schemas/sw-json.cjs +111 -0
  68. package/dist/core/schemas/sw-json.cjs.map +1 -0
  69. package/dist/core/schemas/sw-json.js +110 -0
  70. package/dist/core/schemas/sw-json.js.map +1 -0
  71. package/dist/core/storage.cjs +86 -0
  72. package/dist/core/storage.cjs.map +1 -0
  73. package/dist/core/storage.js +83 -0
  74. package/dist/core/storage.js.map +1 -0
  75. package/dist/core/sw-json-render.cjs +327 -0
  76. package/dist/core/sw-json-render.cjs.map +1 -0
  77. package/dist/core/sw-json-render.js +322 -0
  78. package/dist/core/sw-json-render.js.map +1 -0
  79. package/dist/core/util.cjs +313 -0
  80. package/dist/core/util.cjs.map +1 -0
  81. package/dist/core/util.d.ts +66 -0
  82. package/dist/core/util.d.ts.map +1 -0
  83. package/dist/core/util.js +281 -0
  84. package/dist/core/util.js.map +1 -0
  85. package/dist/defaults.cjs +54 -0
  86. package/dist/defaults.cjs.map +1 -0
  87. package/dist/defaults.d.ts +21 -0
  88. package/dist/defaults.d.ts.map +1 -0
  89. package/dist/defaults.js +37 -0
  90. package/dist/defaults.js.map +1 -0
  91. package/dist/index.cjs +31 -0
  92. package/dist/index.cjs.map +1 -0
  93. package/dist/index.d.ts +20 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +12 -0
  96. package/dist/index.js.map +1 -0
  97. package/package.json +56 -0
  98. package/src/__test__/Dockerfile +1 -0
  99. package/src/__test__/docker.test.ts +67 -0
  100. package/src/__test__/package.json +39 -0
  101. package/src/__test__/python-example/main.py +1 -0
  102. package/src/__test__/python-example/requirements.txt +0 -0
  103. package/src/__test__/vite.config.mts +7 -0
  104. package/src/core/__tests__/docker-conda.test.ts +145 -0
  105. package/src/core/__tests__/docker-entrypoint-generation.test.ts +119 -0
  106. package/src/core/__tests__/docker-python.test.ts +374 -0
  107. package/src/core/__tests__/publish-docker-images.test.ts +309 -0
  108. package/src/core/archive.ts +102 -0
  109. package/src/core/conda/builder.test.ts +71 -0
  110. package/src/core/conda/builder.ts +384 -0
  111. package/src/core/conda/validate-spec.test.ts +213 -0
  112. package/src/core/conda/validate-spec.ts +107 -0
  113. package/src/core/core.ts +835 -0
  114. package/src/core/docker-conda.ts +149 -0
  115. package/src/core/docker-python.ts +283 -0
  116. package/src/core/docker.ts +300 -0
  117. package/src/core/envs.ts +31 -0
  118. package/src/core/package-info.test.ts +82 -0
  119. package/src/core/package-info.ts +843 -0
  120. package/src/core/paths.ts +16 -0
  121. package/src/core/resolver.ts +195 -0
  122. package/src/core/schemas/artifacts.test.ts +72 -0
  123. package/src/core/schemas/artifacts.ts +279 -0
  124. package/src/core/schemas/entrypoints.test.ts +171 -0
  125. package/src/core/schemas/entrypoints.ts +150 -0
  126. package/src/core/schemas/sw-json.ts +216 -0
  127. package/src/core/schemas/test-artifacts.ts +362 -0
  128. package/src/core/storage.ts +125 -0
  129. package/src/core/sw-json-render.test.ts +215 -0
  130. package/src/core/sw-json-render.ts +682 -0
  131. package/src/core/util.ts +390 -0
  132. package/src/defaults.ts +38 -0
  133. package/src/index.ts +31 -0
  134. package/src/requirements.txt +1 -0
@@ -0,0 +1,171 @@
1
+ import { test, expect } from "vitest";
2
+ import type { z } from "zod/v4";
3
+ import * as entrypoints from "./entrypoints";
4
+ import * as testArtifacts from "./test-artifacts";
5
+
6
+ const parseJSON = <T extends z.ZodTypeAny>(data: string, schema: T): z.infer<T> => {
7
+ const parsedData: unknown = JSON.parse(data);
8
+ return schema.parse(parsedData);
9
+ };
10
+
11
+ test.for([
12
+ {
13
+ epTypes: ["environment"],
14
+ artType: "environment",
15
+ variant: "minimal",
16
+ data: testArtifacts.JavaEnvironmentEntrypoint,
17
+ },
18
+ {
19
+ epTypes: ["environment"],
20
+ artType: "environment",
21
+ variant: "with reference",
22
+ data: testArtifacts.JavaEnvironmentEntrypointWithReference,
23
+ },
24
+ { epTypes: ["asset"], artType: "asset", variant: "minimal", data: testArtifacts.AssetEntrypoint },
25
+ {
26
+ epTypes: ["binary"],
27
+ artType: "binary",
28
+ variant: "minimal",
29
+ data: testArtifacts.BinaryEntrypoint,
30
+ },
31
+ {
32
+ epTypes: ["binary"],
33
+ artType: "binary",
34
+ variant: "with reference",
35
+ data: testArtifacts.BinaryEntrypointWithReference,
36
+ },
37
+ {
38
+ epTypes: ["binary"],
39
+ artType: "binary",
40
+ variant: "limited platforms",
41
+ data: testArtifacts.LimitedPlatformsBinaryEntrypoint,
42
+ },
43
+ {
44
+ epTypes: ["binary"],
45
+ artType: "binary",
46
+ variant: "version override",
47
+ data: testArtifacts.CustomBinaryEntrypoint,
48
+ },
49
+ {
50
+ epTypes: ["binary"],
51
+ artType: "binary",
52
+ variant: "version docker",
53
+ data: testArtifacts.BinaryEntrypointWithDocker,
54
+ },
55
+ { epTypes: ["binary"], artType: "java", variant: "minimal", data: testArtifacts.JavaEntrypoint },
56
+ {
57
+ epTypes: ["binary"],
58
+ artType: "java",
59
+ variant: "with reference",
60
+ data: testArtifacts.JavaEntrypointWithReference,
61
+ },
62
+ {
63
+ epTypes: ["binary", "docker"],
64
+ artType: "java",
65
+ variant: "with docker",
66
+ data: testArtifacts.JavaEntrypointWithDocker,
67
+ },
68
+ {
69
+ epTypes: ["binary"],
70
+ artType: "python",
71
+ variant: "minimal",
72
+ data: testArtifacts.PythonEntrypoint,
73
+ },
74
+ {
75
+ epTypes: ["binary"],
76
+ artType: "python",
77
+ variant: "with reference",
78
+ data: testArtifacts.PythonEntrypointWithReference,
79
+ },
80
+ {
81
+ epTypes: ["binary", "docker"],
82
+ artType: "python",
83
+ variant: "with docker",
84
+ data: testArtifacts.PythonEntrypointWithDocker,
85
+ },
86
+ {
87
+ epTypes: ["binary"],
88
+ artType: "R",
89
+ variant: "with reference",
90
+ data: testArtifacts.REntrypointWithReference,
91
+ },
92
+ { epTypes: ["binary"], artType: "R", variant: "minimal", data: testArtifacts.REntrypoint },
93
+ {
94
+ epTypes: ["binary"],
95
+ artType: "R",
96
+ variant: "with reference",
97
+ data: testArtifacts.REntrypointWithReference,
98
+ },
99
+ {
100
+ epTypes: ["binary", "docker"],
101
+ artType: "R",
102
+ variant: "with docker",
103
+ data: testArtifacts.REntrypointWithDocker,
104
+ },
105
+ { epTypes: ["conda"], artType: "conda", variant: "minimal", data: testArtifacts.CondaEntrypoint },
106
+ {
107
+ epTypes: ["conda"],
108
+ artType: "conda",
109
+ variant: "with reference",
110
+ data: testArtifacts.CondaEntrypointWithReference,
111
+ },
112
+ {
113
+ epTypes: ["conda", "docker"],
114
+ artType: "conda",
115
+ variant: "with docker",
116
+ data: testArtifacts.CondaEntrypointWithDocker,
117
+ },
118
+ {
119
+ epTypes: ["docker"],
120
+ artType: "docker",
121
+ variant: "minimal",
122
+ data: testArtifacts.DockerEntrypoint,
123
+ },
124
+ {
125
+ epTypes: ["docker"],
126
+ artType: "docker",
127
+ variant: "with reference",
128
+ data: testArtifacts.DockerEntrypointWithReference,
129
+ },
130
+ ])("parse $artType artifact ($variant)", ({ epTypes, artType, data }) => {
131
+ const ep = parseJSON(data, entrypoints.entrypointSchema);
132
+ for (const epType of epTypes) {
133
+ switch (epType) {
134
+ case "environment":
135
+ expect(ep.environment).toBeDefined();
136
+ break;
137
+ case "asset":
138
+ expect(ep.asset).toBeDefined();
139
+ break;
140
+ case "binary": {
141
+ expect(ep.binary).toBeDefined();
142
+ const art = ep.binary!.artifact;
143
+ if (typeof art !== "string") {
144
+ expect(art.type).toEqual(artType);
145
+ }
146
+ break;
147
+ }
148
+ case "conda": {
149
+ expect(ep.conda).toBeDefined();
150
+ const art = ep.conda!.artifact;
151
+ if (typeof art !== "string") {
152
+ expect(art.registry).toBeDefined();
153
+ expect(art.spec).toBeDefined();
154
+ }
155
+ break;
156
+ }
157
+ case "docker": {
158
+ expect(ep.docker).toBeDefined();
159
+ const dockerArt = ep.docker!.artifact;
160
+ if (typeof dockerArt !== "string") {
161
+ expect(dockerArt.dockerfile).toBeDefined();
162
+ expect(dockerArt.context).toBeDefined();
163
+ expect(dockerArt.registry).toBeDefined();
164
+ }
165
+ break;
166
+ }
167
+ default:
168
+ throw new Error("epType not covered by test logic");
169
+ }
170
+ }
171
+ });
@@ -0,0 +1,150 @@
1
+ import { z } from "zod/v4";
2
+ import * as artifacts from "./artifacts";
3
+ import * as util from "../util";
4
+
5
+ const envVarsSchema = z.array(
6
+ z
7
+ .string()
8
+ .regex(
9
+ /=/,
10
+ "full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes",
11
+ ),
12
+ );
13
+
14
+ export const EnyrypointReferencePattern =
15
+ /^(?<fullName>(?:(?<scope>@[a-z0-9-.]+)\/)?(?<name>[a-z0-9-.]+))\/(?<path>.*)$/;
16
+
17
+ export const referenceSchema = z
18
+ .string()
19
+ .regex(
20
+ EnyrypointReferencePattern,
21
+ "entrypoint reference must contain full package name and path to the file inside",
22
+ );
23
+
24
+ const orRef = <T extends z.ZodTypeAny>(schema: T) =>
25
+ z.union([
26
+ z
27
+ .string("not a reference to artifact")
28
+ .describe('reference to artifact in "artifacts" section'),
29
+ schema,
30
+ ]);
31
+
32
+ // Common options for all software packages: everything that can be run on backend side.
33
+ export const softwareOptionsSchema = z.strictObject({
34
+ cmd: z
35
+ .array(z.string("command artument must be a string"))
36
+ .min(1, { error: "at least one argument is required" })
37
+ .refine((cmd) => cmd[0].trim() != "", { error: "first cmd argument must be non-empty string" })
38
+ .describe(
39
+ "command to run for this entrypoint. This command will be appended by <args> set inside workflow",
40
+ ),
41
+ envVars: envVarsSchema
42
+ .optional()
43
+ .describe("list of environment variables to be set for this entrypoint"),
44
+ });
45
+ export type softwareOptionsType = z.infer<typeof softwareOptionsSchema>;
46
+
47
+ export const environmentOptionsSchema = z.strictObject({
48
+ artifact: orRef(artifacts.environmentSchema.omit({ type: true })),
49
+ envVars: envVarsSchema
50
+ .optional()
51
+ .describe(
52
+ "list of environment variables to be set for any command inside this run environment",
53
+ ),
54
+ });
55
+
56
+ // Full schema of single entrypoint in block-software.entrypoints
57
+ export const entrypointSchema = z
58
+ .strictObject({
59
+ reference: referenceSchema.optional(),
60
+ asset: orRef(artifacts.assetSchema.omit({ type: true })).optional(),
61
+ environment: environmentOptionsSchema.optional(),
62
+
63
+ binary: z
64
+ .union([
65
+ softwareOptionsSchema.extend({ artifact: orRef(artifacts.binarySchema) }),
66
+ softwareOptionsSchema.extend({ artifact: orRef(artifacts.javaSchema) }),
67
+ softwareOptionsSchema.extend({ artifact: orRef(artifacts.pythonSchema) }),
68
+ softwareOptionsSchema.extend({ artifact: orRef(artifacts.rSchema) }),
69
+ ])
70
+ .optional(), // TODO: reduce nesting: put java, python and r to the level of binary, like conda.
71
+
72
+ conda: softwareOptionsSchema
73
+ .extend({ artifact: orRef(artifacts.condaSchema.omit({ type: true })) })
74
+ .optional(),
75
+ docker: softwareOptionsSchema
76
+ .extend({ artifact: orRef(artifacts.dockerSchema.omit({ type: true })) })
77
+ .optional(),
78
+ })
79
+ .refine(
80
+ (data) => {
81
+ const n =
82
+ util.toInt(data.reference) +
83
+ util.toInt(data.asset && !data.docker) + // no docker for assets
84
+ util.toInt(data.binary || (data.binary && data.docker)) + // allow both docker and binary to be set in single entrypoint
85
+ util.toInt(data.conda || (data.conda && data.docker)) + // allow both docker and conda to be set in single entrypoint
86
+ util.toInt(data.environment && !data.docker); // no docker for environments
87
+
88
+ if (n === 0) {
89
+ return Boolean(data.docker); // allow separate docker entrypoints (without binary/conda/...)
90
+ }
91
+
92
+ return n === 1;
93
+ },
94
+ {
95
+ message:
96
+ "entrypoint cannot point to several packages at once: choose 'reference', 'asset', 'binary', 'environment' or 'docker'",
97
+ path: ["reference | asset | binary | environment | docker"],
98
+ },
99
+ );
100
+ export type entrypointType = z.infer<typeof entrypointSchema>;
101
+
102
+ // Full block-software.entrypoints list schema
103
+ export const entrypointListSchema = z.record(
104
+ z
105
+ .string()
106
+ .regex(/[-_a-z0-9.]/)
107
+ .describe(
108
+ "name of entrypoint descriptor, client should import to use this entrypoint (assets.importSoftware)",
109
+ ),
110
+ entrypointSchema,
111
+ );
112
+ export type entrypointListType = z.infer<typeof entrypointListSchema>;
113
+
114
+ export interface ReferenceEntrypoint {
115
+ type: "reference";
116
+ name: string;
117
+ reference: string;
118
+ }
119
+
120
+ export interface AssetEntrypoint {
121
+ type: "asset";
122
+ name: string;
123
+ artifact: artifacts.withId<artifacts.assetType>;
124
+ }
125
+
126
+ export interface SoftwareEntrypoint {
127
+ type: "software";
128
+ name: string;
129
+ artifact: artifacts.withId<
130
+ | artifacts.binaryType
131
+ | artifacts.condaType
132
+ | artifacts.javaType
133
+ | artifacts.pythonType
134
+ | artifacts.rType
135
+ | artifacts.dockerType
136
+ >;
137
+ cmd: string[];
138
+ env: string[];
139
+ }
140
+
141
+ export interface EnvironmentEntrypoint {
142
+ type: "environment";
143
+ name: string;
144
+ artifact: artifacts.withId<artifacts.environmentType>;
145
+ env: string[];
146
+ }
147
+
148
+ export type PackageEntrypoint = AssetEntrypoint | SoftwareEntrypoint | EnvironmentEntrypoint;
149
+ export type Entrypoint = ReferenceEntrypoint | PackageEntrypoint;
150
+ export type EntrypointType = Extract<Entrypoint, { type: string }>["type"];
@@ -0,0 +1,216 @@
1
+ import { z } from "zod/v4";
2
+ import * as defaults from "../../defaults";
3
+ import * as artifacts from "./artifacts";
4
+ import * as util from "../util";
5
+
6
+ export const remoteLocationSchema = z.object({
7
+ registry: z.string().describe("name of the registry to use for package download"),
8
+ package: z
9
+ .string()
10
+ .describe("full package path in registry, e.g. 'common/jdk/21.0.2.13.1-{os}-{arch}.tgz"),
11
+ });
12
+
13
+ export const assetSchema = z.object({
14
+ ...remoteLocationSchema.shape,
15
+ url: z.string().describe("asset download URL"),
16
+ });
17
+ export type assetInfo = z.infer<typeof assetSchema>;
18
+
19
+ export const dockerSchema = z.object({
20
+ tag: z.string().describe("full image tag to pull on backend side to execute this software"),
21
+ entrypoint: z.array(z.string()).describe("override image's entrypoint"),
22
+ cmd: z.array(z.string()).describe("command to be run in the container"),
23
+
24
+ pkg: z
25
+ .string()
26
+ .default(defaults.DOCKER_PLACEHOLDER_PKG)
27
+ .describe(
28
+ 'what to substitute in place of "{pkg}" variable in "cmd" (for artifacts with docker autogeneration)',
29
+ ),
30
+ });
31
+ export type dockerInfo = z.infer<typeof dockerSchema>;
32
+
33
+ export const runEnvironmentSchema = z.object({
34
+ type: z.enum(artifacts.runEnvironmentTypes),
35
+ ...remoteLocationSchema.shape,
36
+
37
+ ["r-version"]: z.string().optional(),
38
+ ["python-version"]: z.string().optional(),
39
+ ["java-version"]: z.string().optional(),
40
+
41
+ envVars: z
42
+ .array(
43
+ z
44
+ .string()
45
+ .regex(
46
+ /=/,
47
+ "environment variable should be specified in format: <var-name>=<var-value>, i.e.: MY_ENV=value",
48
+ ),
49
+ )
50
+ .optional(),
51
+
52
+ binDir: z.string(),
53
+ });
54
+ export type runEnvInfo = z.infer<typeof runEnvironmentSchema>;
55
+
56
+ export const runDependencyJavaSchema = runEnvironmentSchema.extend({
57
+ type: z.literal("java"),
58
+ name: z
59
+ .string()
60
+ .describe("name used to import this package as software dependency of tengo script"),
61
+ });
62
+ export type runEnvDependencyJava = z.infer<typeof runDependencyJavaSchema>;
63
+
64
+ export const runDependencyPythonSchema = runEnvironmentSchema.extend({
65
+ type: z.literal("python"),
66
+ ["python-version"]: z.string(),
67
+ name: z
68
+ .string()
69
+ .describe("name used to import this package as software dependency of tengo script"),
70
+ });
71
+ export type runEnvDependencyPython = z.infer<typeof runDependencyPythonSchema>;
72
+
73
+ export const runDependencyRSchema = runEnvironmentSchema.extend({
74
+ type: z.literal("R"),
75
+ ["r-version"]: z.string(),
76
+ name: z
77
+ .string()
78
+ .describe("name used to import this package as software dependency of tengo script"),
79
+ });
80
+ export type runEnvDependencyR = z.infer<typeof runDependencyRSchema>;
81
+
82
+ export type runEnvDependency = runEnvDependencyJava | runEnvDependencyPython | runEnvDependencyR;
83
+
84
+ export const commonPackageSettingsSchema = z.object({
85
+ cmd: z.array(z.string()).min(1).describe("run given command, appended by args from workflow"),
86
+
87
+ envVars: z
88
+ .array(
89
+ z
90
+ .string()
91
+ .regex(
92
+ /=/,
93
+ "full environment variable specification is required: <var-name>=<var-value>, e.g.: IS_CI=yes",
94
+ ),
95
+ )
96
+ .optional(),
97
+ });
98
+
99
+ export const binaryPackageSchema = z.object({
100
+ type: z.literal("binary"),
101
+ ...commonPackageSettingsSchema.shape,
102
+
103
+ pkg: z
104
+ .string()
105
+ .optional()
106
+ .describe("location of all package contents in Docker container (default: /app)"),
107
+ });
108
+
109
+ export const javaPackageSettingsSchema = z.object({
110
+ type: z.literal("java"),
111
+
112
+ ...commonPackageSettingsSchema.shape,
113
+ runEnv: runDependencyJavaSchema,
114
+ });
115
+
116
+ export const pythonPackageSettingsSchema = z.object({
117
+ type: z.literal("python"),
118
+
119
+ ...commonPackageSettingsSchema.shape,
120
+ runEnv: runDependencyPythonSchema,
121
+
122
+ toolset: z.string(),
123
+ dependencies: z
124
+ .record(z.string(), z.string())
125
+ .describe(
126
+ "paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'",
127
+ ),
128
+ });
129
+
130
+ export const rPackageSettingsSchema = z.object({
131
+ type: z.literal("R"),
132
+
133
+ ...commonPackageSettingsSchema.shape,
134
+ runEnv: runDependencyRSchema,
135
+
136
+ toolset: z.string(),
137
+ dependencies: z
138
+ .record(z.string(), z.string())
139
+ .describe(
140
+ "paths of files that describe dependencies for given toolset: say, requirements.txt for 'pip'",
141
+ ),
142
+ });
143
+
144
+ export const condaPackageSchema = z.object({
145
+ type: z.literal("conda"),
146
+ ...commonPackageSettingsSchema.shape,
147
+
148
+ ["micromamba-version"]: z
149
+ .string()
150
+ .describe("version of micromamba to be used to operate with conda environments"),
151
+ ["conda-root-dir"]: z
152
+ .string()
153
+ .default(defaults.CONDA_DATA_LOCATION)
154
+ .describe("root directory of conda environment inside package root"),
155
+
156
+ spec: z
157
+ .string()
158
+ .describe("location of spec.yaml describing conda environment, relative to package root."),
159
+ });
160
+
161
+ export const remoteSoftwareSchema = z.union([
162
+ remoteLocationSchema.extend(binaryPackageSchema.shape),
163
+ remoteLocationSchema.extend(javaPackageSettingsSchema.shape),
164
+ remoteLocationSchema.extend(pythonPackageSettingsSchema.shape),
165
+ remoteLocationSchema.extend(rPackageSettingsSchema.shape),
166
+ remoteLocationSchema.extend(condaPackageSchema.shape),
167
+ ]);
168
+ export type remoteSoftwareType = z.infer<typeof remoteSoftwareSchema>;
169
+
170
+ export const localLocationSchema = z.object({
171
+ hash: z
172
+ .string()
173
+ .describe(
174
+ "hash of software directory. Makes deduplication to work properly when you actively develop software",
175
+ ),
176
+ path: z.string().describe("absolute path to root directory of software on local host"),
177
+ });
178
+
179
+ export const localSoftwareSchema = z.discriminatedUnion("type", [
180
+ localLocationSchema.extend(binaryPackageSchema.shape),
181
+ localLocationSchema.extend(javaPackageSettingsSchema.shape),
182
+ localLocationSchema.extend(pythonPackageSettingsSchema.shape),
183
+ localLocationSchema.extend(rPackageSettingsSchema.shape),
184
+ localLocationSchema.extend(condaPackageSchema.shape),
185
+ // Docker can be used 'as usual' without any special 'local' section magic
186
+ ]);
187
+ export type localSoftwareType = z.infer<typeof localSoftwareSchema>;
188
+
189
+ // Full .sw.json file schema
190
+ export const swJsonSchema = z
191
+ .object({
192
+ isDev: z.boolean().optional(),
193
+
194
+ asset: assetSchema.optional(),
195
+ binary: remoteSoftwareSchema.optional(),
196
+ docker: dockerSchema.optional(),
197
+ runEnv: runEnvironmentSchema.optional(),
198
+ local: localSoftwareSchema.optional(),
199
+ })
200
+ .refine(
201
+ (data) =>
202
+ util.toInt(data.runEnv) +
203
+ util.toInt(data.binary || data.docker) + // allow both docker and binary to be set in single entrypoint
204
+ util.toInt(data.asset) +
205
+ util.toInt(data.local) ==
206
+ 1,
207
+ {
208
+ message:
209
+ "entrypoint cannot point to several packages at once: choose 'environment', 'binary', 'asset', 'conda' or 'local'",
210
+ path: ["environment | binary | asset | conda | local"],
211
+ },
212
+ );
213
+
214
+ export type swJsonType = z.infer<typeof swJsonSchema> & {
215
+ id: util.artifactID;
216
+ };