@expo/steps 0.0.4 → 0.0.5

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 (42) hide show
  1. package/README.md +4 -0
  2. package/dist_commonjs/BuildConfig.cjs +85 -27
  3. package/dist_commonjs/BuildConfig.d.ts +41 -13
  4. package/dist_commonjs/BuildConfig.js.map +1 -1
  5. package/dist_commonjs/BuildConfigParser.cjs +92 -25
  6. package/dist_commonjs/BuildConfigParser.d.ts +7 -2
  7. package/dist_commonjs/BuildConfigParser.js.map +1 -1
  8. package/dist_commonjs/BuildFunction.cjs +40 -0
  9. package/dist_commonjs/BuildFunction.d.ts +32 -0
  10. package/dist_commonjs/BuildFunction.js.map +1 -0
  11. package/dist_commonjs/BuildPlatform.cjs +9 -0
  12. package/dist_commonjs/BuildPlatform.d.ts +4 -0
  13. package/dist_commonjs/BuildPlatform.js.map +1 -0
  14. package/dist_commonjs/BuildStepInput.cjs +1 -1
  15. package/dist_commonjs/BuildStepInput.d.ts +1 -0
  16. package/dist_commonjs/BuildStepInput.js.map +1 -1
  17. package/dist_commonjs/BuildStepOutput.d.ts +1 -0
  18. package/dist_commonjs/BuildStepOutput.js.map +1 -1
  19. package/dist_commonjs/BuildWorkflow.cjs +6 -3
  20. package/dist_commonjs/BuildWorkflow.d.ts +4 -1
  21. package/dist_commonjs/BuildWorkflow.js.map +1 -1
  22. package/dist_esm/BuildConfig.d.ts +41 -13
  23. package/dist_esm/BuildConfig.js +79 -25
  24. package/dist_esm/BuildConfig.js.map +1 -1
  25. package/dist_esm/BuildConfigParser.d.ts +7 -2
  26. package/dist_esm/BuildConfigParser.js +93 -26
  27. package/dist_esm/BuildConfigParser.js.map +1 -1
  28. package/dist_esm/BuildFunction.d.ts +32 -0
  29. package/dist_esm/BuildFunction.js +36 -0
  30. package/dist_esm/BuildFunction.js.map +1 -0
  31. package/dist_esm/BuildPlatform.d.ts +4 -0
  32. package/dist_esm/BuildPlatform.js +6 -0
  33. package/dist_esm/BuildPlatform.js.map +1 -0
  34. package/dist_esm/BuildStepInput.d.ts +1 -0
  35. package/dist_esm/BuildStepInput.js +1 -1
  36. package/dist_esm/BuildStepInput.js.map +1 -1
  37. package/dist_esm/BuildStepOutput.d.ts +1 -0
  38. package/dist_esm/BuildStepOutput.js.map +1 -1
  39. package/dist_esm/BuildWorkflow.d.ts +4 -1
  40. package/dist_esm/BuildWorkflow.js +6 -3
  41. package/dist_esm/BuildWorkflow.js.map +1 -1
  42. package/package.json +2 -2
@@ -4,9 +4,10 @@ exports.BuildWorkflow = void 0;
4
4
  const BuildArtifacts_js_1 = require("./BuildArtifacts.cjs");
5
5
  const BuildTemporaryFiles_js_1 = require("./BuildTemporaryFiles.cjs");
6
6
  class BuildWorkflow {
7
- constructor(ctx, { buildSteps }) {
7
+ constructor(ctx, { buildSteps, buildFunctions }) {
8
8
  this.ctx = ctx;
9
9
  this.buildSteps = buildSteps;
10
+ this.buildFunctions = buildFunctions;
10
11
  }
11
12
  async executeAsync(env = process.env) {
12
13
  for (const step of this.buildSteps) {
@@ -17,8 +18,10 @@ class BuildWorkflow {
17
18
  const applicationArchives = await (0, BuildTemporaryFiles_js_1.findArtifactsByTypeAsync)(this.ctx, BuildArtifacts_js_1.BuildArtifactType.APPLICATION_ARCHIVE);
18
19
  const buildArtifacts = await (0, BuildTemporaryFiles_js_1.findArtifactsByTypeAsync)(this.ctx, BuildArtifacts_js_1.BuildArtifactType.BUILD_ARTIFACT);
19
20
  return {
20
- [BuildArtifacts_js_1.BuildArtifactType.APPLICATION_ARCHIVE]: applicationArchives,
21
- [BuildArtifacts_js_1.BuildArtifactType.BUILD_ARTIFACT]: buildArtifacts,
21
+ ...(applicationArchives.length > 0 && {
22
+ [BuildArtifacts_js_1.BuildArtifactType.APPLICATION_ARCHIVE]: applicationArchives,
23
+ }),
24
+ ...(buildArtifacts.length > 0 && { [BuildArtifacts_js_1.BuildArtifactType.BUILD_ARTIFACT]: buildArtifacts }),
22
25
  };
23
26
  }
24
27
  async cleanUpAsync() {
@@ -1,12 +1,15 @@
1
1
  import { BuildArtifacts } from './BuildArtifacts.js';
2
+ import { BuildFunctionById } from './BuildFunction.js';
2
3
  import { BuildStep } from './BuildStep.js';
3
4
  import { BuildStepContext } from './BuildStepContext.js';
4
5
  import { BuildStepEnv } from './BuildStepEnv.js';
5
6
  export declare class BuildWorkflow {
6
7
  private readonly ctx;
7
8
  readonly buildSteps: BuildStep[];
8
- constructor(ctx: BuildStepContext, { buildSteps }: {
9
+ readonly buildFunctions: BuildFunctionById;
10
+ constructor(ctx: BuildStepContext, { buildSteps, buildFunctions }: {
9
11
  buildSteps: BuildStep[];
12
+ buildFunctions: BuildFunctionById;
10
13
  });
11
14
  executeAsync(env?: BuildStepEnv): Promise<void>;
12
15
  collectArtifactsAsync(): Promise<BuildArtifacts>;
@@ -1 +1 @@
1
- {"version":3,"file":"BuildWorkflow.js","sourceRoot":"","sources":["../src/BuildWorkflow.ts"],"names":[],"mappings":";;;AAAA,2DAAwE;AAIxE,qEAGkC;AAElC,MAAa,aAAa;IAGxB,YAA6B,GAAqB,EAAE,EAAE,UAAU,EAA+B;QAAlE,QAAG,GAAH,GAAG,CAAkB;QAChD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,MAAoB,OAAO,CAAC,GAAG;QACvD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;YAClC,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;SAC9B;IACH,CAAC;IAEM,KAAK,CAAC,qBAAqB;QAChC,MAAM,mBAAmB,GAAG,MAAM,IAAA,iDAAwB,EACxD,IAAI,CAAC,GAAG,EACR,qCAAiB,CAAC,mBAAmB,CACtC,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,IAAA,iDAAwB,EACnD,IAAI,CAAC,GAAG,EACR,qCAAiB,CAAC,cAAc,CACjC,CAAC;QACF,OAAO;YACL,CAAC,qCAAiB,CAAC,mBAAmB,CAAC,EAAE,mBAAmB;YAC5D,CAAC,qCAAiB,CAAC,cAAc,CAAC,EAAE,cAAc;SACnD,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,YAAY;QACvB,MAAM,IAAA,iEAAwC,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;CACF;AA/BD,sCA+BC","sourcesContent":["import { BuildArtifacts, BuildArtifactType } from './BuildArtifacts.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepEnv } from './BuildStepEnv.js';\nimport {\n cleanUpWorkflowTemporaryDirectoriesAsync,\n findArtifactsByTypeAsync,\n} from './BuildTemporaryFiles.js';\n\nexport class BuildWorkflow {\n public readonly buildSteps: BuildStep[];\n\n constructor(private readonly ctx: BuildStepContext, { buildSteps }: { buildSteps: BuildStep[] }) {\n this.buildSteps = buildSteps;\n }\n\n public async executeAsync(env: BuildStepEnv = process.env): Promise<void> {\n for (const step of this.buildSteps) {\n await step.executeAsync(env);\n }\n }\n\n public async collectArtifactsAsync(): Promise<BuildArtifacts> {\n const applicationArchives = await findArtifactsByTypeAsync(\n this.ctx,\n BuildArtifactType.APPLICATION_ARCHIVE\n );\n const buildArtifacts = await findArtifactsByTypeAsync(\n this.ctx,\n BuildArtifactType.BUILD_ARTIFACT\n );\n return {\n [BuildArtifactType.APPLICATION_ARCHIVE]: applicationArchives,\n [BuildArtifactType.BUILD_ARTIFACT]: buildArtifacts,\n };\n }\n\n public async cleanUpAsync(): Promise<void> {\n await cleanUpWorkflowTemporaryDirectoriesAsync(this.ctx);\n }\n}\n"]}
1
+ {"version":3,"file":"BuildWorkflow.js","sourceRoot":"","sources":["../src/BuildWorkflow.ts"],"names":[],"mappings":";;;AAAA,2DAAwE;AAKxE,qEAGkC;AAElC,MAAa,aAAa;IAIxB,YACmB,GAAqB,EACtC,EAAE,UAAU,EAAE,cAAc,EAAkE;QAD7E,QAAG,GAAH,GAAG,CAAkB;QAGtC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,MAAoB,OAAO,CAAC,GAAG;QACvD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;YAClC,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;SAC9B;IACH,CAAC;IAEM,KAAK,CAAC,qBAAqB;QAChC,MAAM,mBAAmB,GAAG,MAAM,IAAA,iDAAwB,EACxD,IAAI,CAAC,GAAG,EACR,qCAAiB,CAAC,mBAAmB,CACtC,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,IAAA,iDAAwB,EACnD,IAAI,CAAC,GAAG,EACR,qCAAiB,CAAC,cAAc,CACjC,CAAC;QACF,OAAO;YACL,GAAG,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,IAAI;gBACpC,CAAC,qCAAiB,CAAC,mBAAmB,CAAC,EAAE,mBAAmB;aAC7D,CAAC;YACF,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,qCAAiB,CAAC,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;SACzF,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,YAAY;QACvB,MAAM,IAAA,iEAAwC,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;CACF;AAtCD,sCAsCC","sourcesContent":["import { BuildArtifacts, BuildArtifactType } from './BuildArtifacts.js';\nimport { BuildFunctionById } from './BuildFunction.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepEnv } from './BuildStepEnv.js';\nimport {\n cleanUpWorkflowTemporaryDirectoriesAsync,\n findArtifactsByTypeAsync,\n} from './BuildTemporaryFiles.js';\n\nexport class BuildWorkflow {\n public readonly buildSteps: BuildStep[];\n public readonly buildFunctions: BuildFunctionById;\n\n constructor(\n private readonly ctx: BuildStepContext,\n { buildSteps, buildFunctions }: { buildSteps: BuildStep[]; buildFunctions: BuildFunctionById }\n ) {\n this.buildSteps = buildSteps;\n this.buildFunctions = buildFunctions;\n }\n\n public async executeAsync(env: BuildStepEnv = process.env): Promise<void> {\n for (const step of this.buildSteps) {\n await step.executeAsync(env);\n }\n }\n\n public async collectArtifactsAsync(): Promise<BuildArtifacts> {\n const applicationArchives = await findArtifactsByTypeAsync(\n this.ctx,\n BuildArtifactType.APPLICATION_ARCHIVE\n );\n const buildArtifacts = await findArtifactsByTypeAsync(\n this.ctx,\n BuildArtifactType.BUILD_ARTIFACT\n );\n return {\n ...(applicationArchives.length > 0 && {\n [BuildArtifactType.APPLICATION_ARCHIVE]: applicationArchives,\n }),\n ...(buildArtifacts.length > 0 && { [BuildArtifactType.BUILD_ARTIFACT]: buildArtifacts }),\n };\n }\n\n public async cleanUpAsync(): Promise<void> {\n await cleanUpWorkflowTemporaryDirectoriesAsync(this.ctx);\n }\n}\n"]}
@@ -1,25 +1,53 @@
1
1
  import Joi from 'joi';
2
+ import { BuildPlatform } from './BuildPlatform.js';
2
3
  export interface BuildConfig {
3
4
  build: {
4
5
  name?: string;
5
6
  steps: BuildStepConfig[];
6
7
  };
8
+ functions?: Record<string, BuildFunctionConfig>;
7
9
  }
8
- export type BuildStepInputsConfig = Record<string, string>;
9
- export type BuildStepOutputsConfig = (string | {
10
- name: string;
11
- required?: boolean;
12
- })[];
13
- export type BuildStepConfig = string | {
14
- run: string | {
15
- id?: string;
16
- inputs?: BuildStepInputsConfig;
17
- outputs?: BuildStepOutputsConfig;
18
- name?: string;
19
- workingDirectory?: string;
20
- shell?: string;
10
+ export type BuildStepConfig = BuildStepCommandRun | BuildStepBareCommandRun | BuildStepFunctionCall | BuildStepBareFunctionCall;
11
+ export type BuildStepCommandRun = {
12
+ run: BuildFunctionCallConfig & {
13
+ outputs?: BuildStepOutputs;
21
14
  command: string;
22
15
  };
23
16
  };
17
+ export type BuildStepBareCommandRun = {
18
+ run: string;
19
+ };
20
+ export type BuildStepFunctionCall = {
21
+ [functionId: string]: BuildFunctionCallConfig;
22
+ };
23
+ export type BuildStepBareFunctionCall = string;
24
+ export type BuildFunctionCallConfig = {
25
+ id?: string;
26
+ inputs?: BuildStepInputs;
27
+ name?: string;
28
+ workingDirectory?: string;
29
+ shell?: string;
30
+ };
31
+ export type BuildStepInputs = Record<string, string>;
32
+ export type BuildStepOutputs = BuildInputOutputParameters;
33
+ export interface BuildFunctionConfig {
34
+ id?: string;
35
+ inputs?: BuildFunctionInputs;
36
+ outputs?: BuildFunctionOutputs;
37
+ name?: string;
38
+ platforms?: BuildPlatform[];
39
+ shell?: string;
40
+ command: string;
41
+ }
42
+ export type BuildFunctionInputs = BuildInputOutputParameters;
43
+ export type BuildFunctionOutputs = BuildInputOutputParameters;
44
+ export type BuildInputOutputParameters = (string | {
45
+ name: string;
46
+ required?: boolean;
47
+ })[];
24
48
  export declare const BuildConfigSchema: Joi.ObjectSchema<BuildConfig>;
49
+ export declare function isBuildStepCommandRun(step: BuildStepConfig): step is BuildStepCommandRun;
50
+ export declare function isBuildStepBareCommandRun(step: BuildStepConfig): step is BuildStepBareCommandRun;
51
+ export declare function isBuildStepFunctionCall(step: BuildStepConfig): step is BuildStepFunctionCall;
52
+ export declare function isBuildStepBareFunctionCall(step: BuildStepConfig): step is BuildStepBareFunctionCall;
25
53
  export declare function validateBuildConfig(rawConfig: object): BuildConfig;
@@ -1,34 +1,68 @@
1
+ import assert from 'assert';
1
2
  import Joi from 'joi';
2
3
  import { BuildConfigError } from './errors/BuildConfigError.js';
4
+ import { BuildPlatform } from './BuildPlatform.js';
5
+ const BuildInputOutputParametersSchema = Joi.array().items(Joi.alternatives().try(Joi.string().required(), Joi.object({
6
+ name: Joi.string().required(),
7
+ required: Joi.boolean(),
8
+ }).required()));
9
+ const BuildFunctionCallSchema = Joi.object({
10
+ id: Joi.string(),
11
+ inputs: Joi.object().pattern(Joi.string(), Joi.string()),
12
+ name: Joi.string(),
13
+ workingDirectory: Joi.string(),
14
+ shell: Joi.string(),
15
+ }).rename('working_directory', 'workingDirectory');
16
+ const BuildStepConfigSchema = Joi.any()
17
+ .when(Joi.object().pattern(Joi.string().disallow('run').required(), Joi.object().unknown().required()), {
18
+ then: Joi.object().pattern(Joi.string().disallow('run').min(1).required(), BuildFunctionCallSchema.required(), { matches: Joi.array().length(1) }),
19
+ })
20
+ .when(Joi.object({ run: Joi.object().unknown().required() }), {
21
+ then: Joi.object({
22
+ run: BuildFunctionCallSchema.keys({
23
+ outputs: BuildInputOutputParametersSchema,
24
+ command: Joi.string().required(),
25
+ }),
26
+ }),
27
+ })
28
+ .when(Joi.object({ run: Joi.string().required() }), {
29
+ then: Joi.object({
30
+ run: Joi.string().min(1).required(),
31
+ }),
32
+ })
33
+ .when(Joi.string(), {
34
+ then: Joi.string().min(1),
35
+ });
36
+ const BuildFunctionSchema = Joi.object({
37
+ id: Joi.string(),
38
+ name: Joi.string(),
39
+ platforms: Joi.string().allow(...Object.values(BuildPlatform)),
40
+ inputs: BuildInputOutputParametersSchema,
41
+ outputs: BuildInputOutputParametersSchema,
42
+ command: Joi.string().required(),
43
+ shell: Joi.string(),
44
+ });
3
45
  export const BuildConfigSchema = Joi.object({
4
46
  build: Joi.object({
5
47
  name: Joi.string(),
6
- steps: Joi.array()
7
- .items(Joi.object({
8
- run: Joi.alternatives().conditional('run', {
9
- is: Joi.string(),
10
- then: Joi.string().required(),
11
- otherwise: Joi.object({
12
- id: Joi.string(),
13
- inputs: Joi.object().pattern(Joi.string(), Joi.string()),
14
- outputs: Joi.array().items(Joi.alternatives().try(Joi.string().required(), Joi.object({
15
- name: Joi.string().required(),
16
- required: Joi.boolean(),
17
- }).required())),
18
- name: Joi.string(),
19
- workingDirectory: Joi.string(),
20
- shell: Joi.string(),
21
- command: Joi.string().required(),
22
- })
23
- .rename('working_directory', 'workingDirectory')
24
- .required(),
25
- }),
26
- }))
27
- .required(),
48
+ steps: Joi.array().items(BuildStepConfigSchema.required()).required(),
28
49
  }).required(),
50
+ functions: Joi.object().pattern(Joi.string().min(1).required().disallow('run'), BuildFunctionSchema.required()),
29
51
  }).required();
52
+ export function isBuildStepCommandRun(step) {
53
+ return typeof step === 'object' && typeof step.run === 'object';
54
+ }
55
+ export function isBuildStepBareCommandRun(step) {
56
+ return typeof step === 'object' && typeof step.run === 'string';
57
+ }
58
+ export function isBuildStepFunctionCall(step) {
59
+ return typeof step === 'object' && !('run' in step);
60
+ }
61
+ export function isBuildStepBareFunctionCall(step) {
62
+ return typeof step === 'string';
63
+ }
30
64
  export function validateBuildConfig(rawConfig) {
31
- const { error, value } = BuildConfigSchema.validate(rawConfig, {
65
+ const { error, value: buildConfig } = BuildConfigSchema.validate(rawConfig, {
32
66
  allowUnknown: false,
33
67
  abortEarly: false,
34
68
  });
@@ -36,8 +70,28 @@ export function validateBuildConfig(rawConfig) {
36
70
  const errorMessage = error.details.map(({ message }) => message).join(', ');
37
71
  throw new BuildConfigError(errorMessage, { cause: error });
38
72
  }
39
- else {
40
- return value;
73
+ validateAllFunctionsExist(buildConfig);
74
+ return buildConfig;
75
+ }
76
+ function validateAllFunctionsExist(config) {
77
+ const calledFunctionsSet = new Set();
78
+ for (const step of config.build.steps) {
79
+ if (typeof step === 'string') {
80
+ calledFunctionsSet.add(step);
81
+ }
82
+ else if (!('run' in step)) {
83
+ const keys = Object.keys(step);
84
+ assert(keys.length === 1, 'There must be at most one function call in the step (enforced by joi)');
85
+ calledFunctionsSet.add(keys[0]);
86
+ }
87
+ }
88
+ const calledFunctions = Array.from(calledFunctionsSet);
89
+ const nonExistentFunctions = calledFunctions.filter((calledFunction) => {
90
+ var _a;
91
+ return !(calledFunction in ((_a = config.functions) !== null && _a !== void 0 ? _a : {}));
92
+ });
93
+ if (nonExistentFunctions.length > 0) {
94
+ throw new BuildConfigError(`Calling non-existent functions: ${nonExistentFunctions.join(', ')}`);
41
95
  }
42
96
  }
43
97
  //# sourceMappingURL=BuildConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuildConfig.js","sourceRoot":"","sources":["../src/BuildConfig.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAmChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAc;IACvD,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;aACf,KAAK,CACJ,GAAG,CAAC,MAAM,CAAC;YACT,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE;gBACzC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE;gBAChB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC;oBACpB,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE;oBAChB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;oBACxD,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CACxB,GAAG,CAAC,YAAY,EAAE,CAAC,GAAG,CACpB,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EACvB,GAAG,CAAC,MAAM,CAAC;wBACT,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;wBAC7B,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE;qBACxB,CAAC,CAAC,QAAQ,EAAE,CACd,CACF;oBACD,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE;oBAClB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE;oBAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;oBACnB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;iBACjC,CAAC;qBACC,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;qBAC/C,QAAQ,EAAE;aACd,CAAC;SACH,CAAC,CACH;aACA,QAAQ,EAAE;KACd,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEd,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,SAAS,EAAE;QAC7D,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IACH,IAAI,KAAK,EAAE;QACT,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5E,MAAM,IAAI,gBAAgB,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;KAC5D;SAAM;QACL,OAAO,KAAK,CAAC;KACd;AACH,CAAC","sourcesContent":["import Joi from 'joi';\n\nimport { BuildConfigError } from './errors/BuildConfigError.js';\n\nexport interface BuildConfig {\n build: {\n name?: string;\n steps: BuildStepConfig[];\n };\n}\n\nexport type BuildStepInputsConfig = Record<string, string>;\n\nexport type BuildStepOutputsConfig = (\n | string\n | {\n name: string;\n required?: boolean;\n }\n)[];\n\nexport type BuildStepConfig =\n | string\n | {\n run:\n | string\n | {\n id?: string;\n inputs?: BuildStepInputsConfig;\n outputs?: BuildStepOutputsConfig;\n name?: string;\n workingDirectory?: string;\n shell?: string;\n command: string;\n };\n };\n\nexport const BuildConfigSchema = Joi.object<BuildConfig>({\n build: Joi.object({\n name: Joi.string(),\n steps: Joi.array()\n .items(\n Joi.object({\n run: Joi.alternatives().conditional('run', {\n is: Joi.string(),\n then: Joi.string().required(),\n otherwise: Joi.object({\n id: Joi.string(),\n inputs: Joi.object().pattern(Joi.string(), Joi.string()),\n outputs: Joi.array().items(\n Joi.alternatives().try(\n Joi.string().required(),\n Joi.object({\n name: Joi.string().required(),\n required: Joi.boolean(),\n }).required()\n )\n ),\n name: Joi.string(),\n workingDirectory: Joi.string(),\n shell: Joi.string(),\n command: Joi.string().required(),\n })\n .rename('working_directory', 'workingDirectory')\n .required(),\n }),\n })\n )\n .required(),\n }).required(),\n}).required();\n\nexport function validateBuildConfig(rawConfig: object): BuildConfig {\n const { error, value } = BuildConfigSchema.validate(rawConfig, {\n allowUnknown: false,\n abortEarly: false,\n });\n if (error) {\n const errorMessage = error.details.map(({ message }) => message).join(', ');\n throw new BuildConfigError(errorMessage, { cause: error });\n } else {\n return value;\n }\n}\n"]}
1
+ {"version":3,"file":"BuildConfig.js","sourceRoot":"","sources":["../src/BuildConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\n\nimport Joi from 'joi';\n\nimport { BuildConfigError } from './errors/BuildConfigError.js';\nimport { BuildPlatform } from './BuildPlatform.js';\n\nexport interface BuildConfig {\n build: {\n name?: string;\n steps: BuildStepConfig[];\n };\n functions?: Record<string, BuildFunctionConfig>;\n}\n\nexport type BuildStepConfig =\n | BuildStepCommandRun\n | BuildStepBareCommandRun\n | BuildStepFunctionCall\n | BuildStepBareFunctionCall;\n\nexport type BuildStepCommandRun = {\n run: BuildFunctionCallConfig & {\n outputs?: BuildStepOutputs;\n command: string;\n };\n};\nexport type BuildStepBareCommandRun = { run: string };\nexport type BuildStepFunctionCall = {\n [functionId: string]: BuildFunctionCallConfig;\n};\nexport type BuildStepBareFunctionCall = string;\n\nexport type BuildFunctionCallConfig = {\n id?: string;\n inputs?: BuildStepInputs;\n name?: string;\n workingDirectory?: string;\n shell?: string;\n};\n\nexport type BuildStepInputs = Record<string, string>;\nexport type BuildStepOutputs = BuildInputOutputParameters;\n\nexport interface BuildFunctionConfig {\n id?: string;\n inputs?: BuildFunctionInputs;\n outputs?: BuildFunctionOutputs;\n name?: string;\n platforms?: BuildPlatform[];\n shell?: string;\n command: string;\n}\n\nexport type BuildFunctionInputs = BuildInputOutputParameters;\nexport type BuildFunctionOutputs = BuildInputOutputParameters;\n\nexport type BuildInputOutputParameters = (\n | string\n | {\n name: string;\n required?: boolean;\n }\n)[];\n\nconst BuildInputOutputParametersSchema = Joi.array().items(\n Joi.alternatives().try(\n Joi.string().required(),\n Joi.object({\n name: Joi.string().required(),\n required: Joi.boolean(),\n }).required()\n )\n);\n\nconst BuildFunctionCallSchema = Joi.object({\n id: Joi.string(),\n inputs: Joi.object().pattern(Joi.string(), Joi.string()),\n name: Joi.string(),\n workingDirectory: Joi.string(),\n shell: Joi.string(),\n}).rename('working_directory', 'workingDirectory');\n\nconst BuildStepConfigSchema = Joi.any<BuildStepConfig>()\n .when(\n Joi.object().pattern(\n Joi.string().disallow('run').required(),\n Joi.object().unknown().required()\n ),\n {\n then: Joi.object().pattern(\n Joi.string().disallow('run').min(1).required(),\n BuildFunctionCallSchema.required(),\n { matches: Joi.array().length(1) }\n ),\n }\n )\n .when(Joi.object({ run: Joi.object().unknown().required() }), {\n then: Joi.object({\n run: BuildFunctionCallSchema.keys({\n outputs: BuildInputOutputParametersSchema,\n command: Joi.string().required(),\n }),\n }),\n })\n .when(Joi.object({ run: Joi.string().required() }), {\n then: Joi.object({\n run: Joi.string().min(1).required(),\n }),\n })\n .when(Joi.string(), {\n then: Joi.string().min(1),\n });\n\nconst BuildFunctionSchema = Joi.object({\n id: Joi.string(),\n name: Joi.string(),\n platforms: Joi.string().allow(...Object.values(BuildPlatform)),\n inputs: BuildInputOutputParametersSchema,\n outputs: BuildInputOutputParametersSchema,\n command: Joi.string().required(),\n shell: Joi.string(),\n});\n\nexport const BuildConfigSchema = Joi.object<BuildConfig>({\n build: Joi.object({\n name: Joi.string(),\n steps: Joi.array().items(BuildStepConfigSchema.required()).required(),\n }).required(),\n functions: Joi.object().pattern(\n Joi.string().min(1).required().disallow('run'),\n BuildFunctionSchema.required()\n ),\n}).required();\n\nexport function isBuildStepCommandRun(step: BuildStepConfig): step is BuildStepCommandRun {\n return typeof step === 'object' && typeof step.run === 'object';\n}\n\nexport function isBuildStepBareCommandRun(step: BuildStepConfig): step is BuildStepBareCommandRun {\n return typeof step === 'object' && typeof step.run === 'string';\n}\n\nexport function isBuildStepFunctionCall(step: BuildStepConfig): step is BuildStepFunctionCall {\n return typeof step === 'object' && !('run' in step);\n}\n\nexport function isBuildStepBareFunctionCall(\n step: BuildStepConfig\n): step is BuildStepBareFunctionCall {\n return typeof step === 'string';\n}\n\nexport function validateBuildConfig(rawConfig: object): BuildConfig {\n const { error, value: buildConfig } = BuildConfigSchema.validate(rawConfig, {\n allowUnknown: false,\n abortEarly: false,\n });\n if (error) {\n const errorMessage = error.details.map(({ message }) => message).join(', ');\n throw new BuildConfigError(errorMessage, { cause: error });\n }\n validateAllFunctionsExist(buildConfig);\n return buildConfig;\n}\n\nfunction validateAllFunctionsExist(config: BuildConfig): void {\n const calledFunctionsSet = new Set<string>();\n for (const step of config.build.steps) {\n if (typeof step === 'string') {\n calledFunctionsSet.add(step);\n } else if (!('run' in step)) {\n const keys = Object.keys(step);\n assert(\n keys.length === 1,\n 'There must be at most one function call in the step (enforced by joi)'\n );\n calledFunctionsSet.add(keys[0]);\n }\n }\n const calledFunctions = Array.from(calledFunctionsSet);\n const nonExistentFunctions = calledFunctions.filter((calledFunction) => {\n return !(calledFunction in (config.functions ?? {}));\n });\n if (nonExistentFunctions.length > 0) {\n throw new BuildConfigError(\n `Calling non-existent functions: ${nonExistentFunctions.join(', ')}`\n );\n }\n}\n"]}
@@ -9,6 +9,11 @@ export declare class BuildConfigParser {
9
9
  parseAsync(): Promise<BuildWorkflow>;
10
10
  private readRawConfigAsync;
11
11
  private createBuildStepFromConfig;
12
- private createBuildStepInputsFromConfig;
13
- private createBuildStepOutputsFromConfig;
12
+ private createBuildFunctionsFromConfig;
13
+ private createBuildFunctionFromConfig;
14
+ private createBuildStepInputsFromBuildStepInputsDefinition;
15
+ private createBuildStepInputCreatorsFromBuildFunctionInputs;
16
+ private createBuildStepOutputsFromDefinition;
17
+ private createBuildStepOutputCreatorsFromBuildFunctionOutputs;
18
+ private getStepWorkingDirectory;
14
19
  }
@@ -1,8 +1,10 @@
1
+ import assert from 'assert';
1
2
  import fs from 'fs/promises';
2
3
  import path from 'path';
3
4
  import { v4 as uuidv4 } from 'uuid';
4
5
  import YAML from 'yaml';
5
- import { validateBuildConfig, } from './BuildConfig.js';
6
+ import { isBuildStepBareCommandRun, isBuildStepBareFunctionCall, isBuildStepCommandRun, validateBuildConfig, } from './BuildConfig.js';
7
+ import { BuildFunction } from './BuildFunction.js';
6
8
  import { BuildStep } from './BuildStep.js';
7
9
  import { BuildStepInput } from './BuildStepInput.js';
8
10
  import { BuildStepOutput } from './BuildStepOutput.js';
@@ -16,8 +18,9 @@ export class BuildConfigParser {
16
18
  async parseAsync() {
17
19
  const rawConfig = await this.readRawConfigAsync();
18
20
  const config = validateBuildConfig(rawConfig);
19
- const steps = config.build.steps.map((stepConfig) => this.createBuildStepFromConfig(stepConfig));
20
- const workflow = new BuildWorkflow(this.ctx, { buildSteps: steps });
21
+ const buildFunctions = this.createBuildFunctionsFromConfig(config.functions);
22
+ const buildSteps = config.build.steps.map((stepConfig) => this.createBuildStepFromConfig(stepConfig, buildFunctions));
23
+ const workflow = new BuildWorkflow(this.ctx, { buildSteps, buildFunctions });
21
24
  new BuildWorkflowValidator(workflow).validate();
22
25
  return workflow;
23
26
  }
@@ -25,47 +28,94 @@ export class BuildConfigParser {
25
28
  const contents = await fs.readFile(this.configPath, 'utf-8');
26
29
  return YAML.parse(contents);
27
30
  }
28
- createBuildStepFromConfig(buildStepConfig) {
29
- if (typeof buildStepConfig === 'string') {
30
- // TODO: implement calling functions
31
- throw new Error('Not implemented yet');
32
- }
33
- else if (typeof buildStepConfig.run === 'string') {
34
- const command = buildStepConfig.run;
35
- return new BuildStep(this.ctx, {
36
- id: uuidv4(),
37
- workingDirectory: this.ctx.workingDirectory,
38
- command,
39
- });
40
- }
41
- else {
31
+ createBuildStepFromConfig(buildStepConfig, buildFunctions) {
32
+ if (isBuildStepCommandRun(buildStepConfig)) {
42
33
  const { id, inputs: inputsConfig, outputs: outputsConfig, name, workingDirectory, shell, command, } = buildStepConfig.run;
43
34
  const stepId = id !== null && id !== void 0 ? id : uuidv4();
44
- const inputs = inputsConfig && this.createBuildStepInputsFromConfig(inputsConfig, stepId);
45
- const outputs = outputsConfig && this.createBuildStepOutputsFromConfig(outputsConfig, stepId);
35
+ const inputs = inputsConfig &&
36
+ this.createBuildStepInputsFromBuildStepInputsDefinition(inputsConfig, stepId);
37
+ const outputs = outputsConfig && this.createBuildStepOutputsFromDefinition(outputsConfig, stepId);
46
38
  return new BuildStep(this.ctx, {
47
39
  id: stepId,
48
40
  inputs,
49
41
  outputs,
50
42
  name,
51
- workingDirectory: workingDirectory !== undefined
52
- ? path.resolve(this.ctx.workingDirectory, workingDirectory)
53
- : this.ctx.workingDirectory,
43
+ workingDirectory: this.getStepWorkingDirectory(workingDirectory),
54
44
  shell,
55
45
  command,
56
46
  });
57
47
  }
48
+ else if (isBuildStepBareCommandRun(buildStepConfig)) {
49
+ const command = buildStepConfig.run;
50
+ return new BuildStep(this.ctx, {
51
+ id: uuidv4(),
52
+ workingDirectory: this.ctx.workingDirectory,
53
+ command,
54
+ });
55
+ }
56
+ else if (isBuildStepBareFunctionCall(buildStepConfig)) {
57
+ const functionId = buildStepConfig;
58
+ const buildFunction = buildFunctions[functionId];
59
+ return buildFunction.createBuildStepFromFunctionCall({
60
+ workingDirectory: this.getStepWorkingDirectory(),
61
+ });
62
+ }
63
+ else {
64
+ const keys = Object.keys(buildStepConfig);
65
+ assert(keys.length === 1, 'There must be at most one function call in the step (enforced by joi)');
66
+ const functionId = keys[0];
67
+ const buildFunctionCallConfig = buildStepConfig[functionId];
68
+ const buildFunction = buildFunctions[functionId];
69
+ return buildFunction.createBuildStepFromFunctionCall({
70
+ id: buildFunctionCallConfig.id,
71
+ callInputs: buildFunctionCallConfig.inputs,
72
+ workingDirectory: this.getStepWorkingDirectory(buildFunctionCallConfig.workingDirectory),
73
+ shell: buildFunctionCallConfig.shell,
74
+ });
75
+ }
58
76
  }
59
- createBuildStepInputsFromConfig(buildStepInputsConfig, stepId) {
60
- return Object.entries(buildStepInputsConfig).map(([key, value]) => new BuildStepInput(this.ctx, {
77
+ createBuildFunctionsFromConfig(buildFunctionsConfig) {
78
+ if (!buildFunctionsConfig) {
79
+ return {};
80
+ }
81
+ const result = {};
82
+ for (const [functionId, buildFunctionConfig] of Object.entries(buildFunctionsConfig)) {
83
+ result[functionId] = this.createBuildFunctionFromConfig(buildFunctionConfig);
84
+ }
85
+ return result;
86
+ }
87
+ createBuildFunctionFromConfig({ id, name, inputs: inputsConfig, outputs: outputsConfig, shell, command, }) {
88
+ const inputCreators = inputsConfig && this.createBuildStepInputCreatorsFromBuildFunctionInputs(inputsConfig);
89
+ const outputCreators = outputsConfig && this.createBuildStepOutputCreatorsFromBuildFunctionOutputs(outputsConfig);
90
+ return new BuildFunction(this.ctx, { id, name, inputCreators, outputCreators, shell, command });
91
+ }
92
+ createBuildStepInputsFromBuildStepInputsDefinition(buildStepInputs, stepId) {
93
+ return Object.entries(buildStepInputs).map(([key, value]) => new BuildStepInput(this.ctx, {
61
94
  id: key,
62
95
  stepId,
63
96
  defaultValue: value,
64
97
  required: true,
65
98
  }));
66
99
  }
67
- createBuildStepOutputsFromConfig(buildStepOutputsConfig, stepId) {
68
- return buildStepOutputsConfig.map((entry) => {
100
+ createBuildStepInputCreatorsFromBuildFunctionInputs(buildFunctionInputs) {
101
+ return buildFunctionInputs.map((entry) => {
102
+ if (typeof entry === 'string') {
103
+ return (stepId) => new BuildStepInput(this.ctx, { id: entry, stepId });
104
+ }
105
+ else {
106
+ return (stepId) => {
107
+ var _a;
108
+ return new BuildStepInput(this.ctx, {
109
+ id: entry.name,
110
+ required: (_a = entry.required) !== null && _a !== void 0 ? _a : true,
111
+ stepId,
112
+ });
113
+ };
114
+ }
115
+ });
116
+ }
117
+ createBuildStepOutputsFromDefinition(buildStepOutputs, stepId) {
118
+ return buildStepOutputs.map((entry) => {
69
119
  var _a;
70
120
  return typeof entry === 'string'
71
121
  ? new BuildStepOutput(this.ctx, { id: entry, stepId, required: true })
@@ -76,5 +126,22 @@ export class BuildConfigParser {
76
126
  });
77
127
  });
78
128
  }
129
+ createBuildStepOutputCreatorsFromBuildFunctionOutputs(buildFunctionOutputs) {
130
+ return buildFunctionOutputs.map((entry) => typeof entry === 'string'
131
+ ? (stepId) => new BuildStepOutput(this.ctx, { id: entry, stepId, required: true })
132
+ : (stepId) => {
133
+ var _a;
134
+ return new BuildStepOutput(this.ctx, {
135
+ id: entry.name,
136
+ stepId,
137
+ required: (_a = entry.required) !== null && _a !== void 0 ? _a : true,
138
+ });
139
+ });
140
+ }
141
+ getStepWorkingDirectory(workingDirectory) {
142
+ return workingDirectory !== undefined
143
+ ? path.resolve(this.ctx.workingDirectory, workingDirectory)
144
+ : this.ctx.workingDirectory;
145
+ }
79
146
  }
80
147
  //# sourceMappingURL=BuildConfigParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuildConfigParser.js","sourceRoot":"","sources":["../src/BuildConfigParser.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\n\nimport { v4 as uuidv4 } from 'uuid';\nimport YAML from 'yaml';\n\nimport {\n BuildStepConfig,\n BuildStepInputsConfig,\n BuildStepOutputsConfig,\n validateBuildConfig,\n} from './BuildConfig.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepInput } from './BuildStepInput.js';\nimport { BuildStepOutput } from './BuildStepOutput.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildWorkflowValidator } from './BuildWorkflowValidator.js';\n\nexport class BuildConfigParser {\n private readonly configPath: string;\n\n constructor(private readonly ctx: BuildStepContext, { configPath }: { configPath: string }) {\n this.configPath = configPath;\n }\n\n public async parseAsync(): Promise<BuildWorkflow> {\n const rawConfig = await this.readRawConfigAsync();\n const config = validateBuildConfig(rawConfig);\n const steps = config.build.steps.map((stepConfig) =>\n this.createBuildStepFromConfig(stepConfig)\n );\n const workflow = new BuildWorkflow(this.ctx, { buildSteps: steps });\n new BuildWorkflowValidator(workflow).validate();\n return workflow;\n }\n\n private async readRawConfigAsync(): Promise<any> {\n const contents = await fs.readFile(this.configPath, 'utf-8');\n return YAML.parse(contents);\n }\n\n private createBuildStepFromConfig(buildStepConfig: BuildStepConfig): BuildStep {\n if (typeof buildStepConfig === 'string') {\n // TODO: implement calling functions\n throw new Error('Not implemented yet');\n } else if (typeof buildStepConfig.run === 'string') {\n const command = buildStepConfig.run;\n return new BuildStep(this.ctx, {\n id: uuidv4(),\n workingDirectory: this.ctx.workingDirectory,\n command,\n });\n } else {\n const {\n id,\n inputs: inputsConfig,\n outputs: outputsConfig,\n name,\n workingDirectory,\n shell,\n command,\n } = buildStepConfig.run;\n const stepId = id ?? uuidv4();\n const inputs = inputsConfig && this.createBuildStepInputsFromConfig(inputsConfig, stepId);\n const outputs = outputsConfig && this.createBuildStepOutputsFromConfig(outputsConfig, stepId);\n return new BuildStep(this.ctx, {\n id: stepId,\n inputs,\n outputs,\n name,\n workingDirectory:\n workingDirectory !== undefined\n ? path.resolve(this.ctx.workingDirectory, workingDirectory)\n : this.ctx.workingDirectory,\n shell,\n command,\n });\n }\n }\n\n private createBuildStepInputsFromConfig(\n buildStepInputsConfig: BuildStepInputsConfig,\n stepId: string\n ): BuildStepInput[] {\n return Object.entries(buildStepInputsConfig).map(\n ([key, value]) =>\n new BuildStepInput(this.ctx, {\n id: key,\n stepId,\n defaultValue: value,\n required: true,\n })\n );\n }\n\n private createBuildStepOutputsFromConfig(\n buildStepOutputsConfig: BuildStepOutputsConfig,\n stepId: string\n ): BuildStepOutput[] {\n return buildStepOutputsConfig.map((entry) =>\n typeof entry === 'string'\n ? new BuildStepOutput(this.ctx, { id: entry, stepId, required: true })\n : new BuildStepOutput(this.ctx, {\n id: entry.name,\n stepId,\n required: entry.required ?? true,\n })\n );\n }\n}\n"]}
1
+ {"version":3,"file":"BuildConfigParser.js","sourceRoot":"","sources":["../src/BuildConfigParser.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { v4 as uuidv4 } from 'uuid';\nimport YAML from 'yaml';\n\nimport {\n BuildConfig,\n BuildFunctionConfig,\n BuildFunctionInputs,\n BuildFunctionOutputs,\n BuildStepConfig,\n BuildStepInputs,\n BuildStepOutputs,\n isBuildStepBareCommandRun,\n isBuildStepBareFunctionCall,\n isBuildStepCommandRun,\n validateBuildConfig,\n} from './BuildConfig.js';\nimport { BuildFunction, BuildFunctionById } from './BuildFunction.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepInput, BuildStepInputCreator } from './BuildStepInput.js';\nimport { BuildStepOutput, BuildStepOutputCreator } from './BuildStepOutput.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildWorkflowValidator } from './BuildWorkflowValidator.js';\n\nexport class BuildConfigParser {\n private readonly configPath: string;\n\n constructor(private readonly ctx: BuildStepContext, { configPath }: { configPath: string }) {\n this.configPath = configPath;\n }\n\n public async parseAsync(): Promise<BuildWorkflow> {\n const rawConfig = await this.readRawConfigAsync();\n const config = validateBuildConfig(rawConfig);\n const buildFunctions = this.createBuildFunctionsFromConfig(config.functions);\n const buildSteps = config.build.steps.map((stepConfig) =>\n this.createBuildStepFromConfig(stepConfig, buildFunctions)\n );\n const workflow = new BuildWorkflow(this.ctx, { buildSteps, buildFunctions });\n new BuildWorkflowValidator(workflow).validate();\n return workflow;\n }\n\n private async readRawConfigAsync(): Promise<any> {\n const contents = await fs.readFile(this.configPath, 'utf-8');\n return YAML.parse(contents);\n }\n\n private createBuildStepFromConfig(\n buildStepConfig: BuildStepConfig,\n buildFunctions: BuildFunctionById\n ): BuildStep {\n if (isBuildStepCommandRun(buildStepConfig)) {\n const {\n id,\n inputs: inputsConfig,\n outputs: outputsConfig,\n name,\n workingDirectory,\n shell,\n command,\n } = buildStepConfig.run;\n const stepId = id ?? uuidv4();\n const inputs =\n inputsConfig &&\n this.createBuildStepInputsFromBuildStepInputsDefinition(inputsConfig, stepId);\n const outputs =\n outputsConfig && this.createBuildStepOutputsFromDefinition(outputsConfig, stepId);\n return new BuildStep(this.ctx, {\n id: stepId,\n inputs,\n outputs,\n name,\n workingDirectory: this.getStepWorkingDirectory(workingDirectory),\n shell,\n command,\n });\n } else if (isBuildStepBareCommandRun(buildStepConfig)) {\n const command = buildStepConfig.run;\n return new BuildStep(this.ctx, {\n id: uuidv4(),\n workingDirectory: this.ctx.workingDirectory,\n command,\n });\n } else if (isBuildStepBareFunctionCall(buildStepConfig)) {\n const functionId = buildStepConfig;\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall({\n workingDirectory: this.getStepWorkingDirectory(),\n });\n } else {\n const keys = Object.keys(buildStepConfig);\n assert(\n keys.length === 1,\n 'There must be at most one function call in the step (enforced by joi)'\n );\n const functionId = keys[0];\n const buildFunctionCallConfig = buildStepConfig[functionId];\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall({\n id: buildFunctionCallConfig.id,\n callInputs: buildFunctionCallConfig.inputs,\n workingDirectory: this.getStepWorkingDirectory(buildFunctionCallConfig.workingDirectory),\n shell: buildFunctionCallConfig.shell,\n });\n }\n }\n\n private createBuildFunctionsFromConfig(\n buildFunctionsConfig: BuildConfig['functions']\n ): BuildFunctionById {\n if (!buildFunctionsConfig) {\n return {};\n }\n const result: BuildFunctionById = {};\n for (const [functionId, buildFunctionConfig] of Object.entries(buildFunctionsConfig)) {\n result[functionId] = this.createBuildFunctionFromConfig(buildFunctionConfig);\n }\n return result;\n }\n\n private createBuildFunctionFromConfig({\n id,\n name,\n inputs: inputsConfig,\n outputs: outputsConfig,\n shell,\n command,\n }: BuildFunctionConfig): BuildFunction {\n const inputCreators =\n inputsConfig && this.createBuildStepInputCreatorsFromBuildFunctionInputs(inputsConfig);\n const outputCreators =\n outputsConfig && this.createBuildStepOutputCreatorsFromBuildFunctionOutputs(outputsConfig);\n return new BuildFunction(this.ctx, { id, name, inputCreators, outputCreators, shell, command });\n }\n\n private createBuildStepInputsFromBuildStepInputsDefinition(\n buildStepInputs: BuildStepInputs,\n stepId: string\n ): BuildStepInput[] {\n return Object.entries(buildStepInputs).map(\n ([key, value]) =>\n new BuildStepInput(this.ctx, {\n id: key,\n stepId,\n defaultValue: value,\n required: true,\n })\n );\n }\n\n private createBuildStepInputCreatorsFromBuildFunctionInputs(\n buildFunctionInputs: BuildFunctionInputs\n ): BuildStepInputCreator[] {\n return buildFunctionInputs.map((entry) => {\n if (typeof entry === 'string') {\n return (stepId: string) => new BuildStepInput(this.ctx, { id: entry, stepId });\n } else {\n return (stepId: string) =>\n new BuildStepInput(this.ctx, {\n id: entry.name,\n required: entry.required ?? true,\n stepId,\n });\n }\n });\n }\n\n private createBuildStepOutputsFromDefinition(\n buildStepOutputs: BuildStepOutputs,\n stepId: string\n ): BuildStepOutput[] {\n return buildStepOutputs.map((entry) =>\n typeof entry === 'string'\n ? new BuildStepOutput(this.ctx, { id: entry, stepId, required: true })\n : new BuildStepOutput(this.ctx, {\n id: entry.name,\n stepId,\n required: entry.required ?? true,\n })\n );\n }\n\n private createBuildStepOutputCreatorsFromBuildFunctionOutputs(\n buildFunctionOutputs: BuildFunctionOutputs\n ): BuildStepOutputCreator[] {\n return buildFunctionOutputs.map((entry) =>\n typeof entry === 'string'\n ? (stepId: string) => new BuildStepOutput(this.ctx, { id: entry, stepId, required: true })\n : (stepId: string) =>\n new BuildStepOutput(this.ctx, {\n id: entry.name,\n stepId,\n required: entry.required ?? true,\n })\n );\n }\n\n private getStepWorkingDirectory(workingDirectory?: string): string {\n return workingDirectory !== undefined\n ? path.resolve(this.ctx.workingDirectory, workingDirectory)\n : this.ctx.workingDirectory;\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { BuildPlatform } from './BuildPlatform.js';
2
+ import { BuildStep } from './BuildStep.js';
3
+ import { BuildStepContext } from './BuildStepContext.js';
4
+ import { BuildStepInputCreator } from './BuildStepInput.js';
5
+ import { BuildStepOutputCreator } from './BuildStepOutput.js';
6
+ export type BuildFunctionById = Record<string, BuildFunction>;
7
+ export type BuildFunctionCallInputs = Record<string, string>;
8
+ export declare class BuildFunction {
9
+ private readonly ctx;
10
+ readonly id?: string;
11
+ readonly name?: string;
12
+ readonly platforms?: BuildPlatform[];
13
+ readonly inputCreators?: BuildStepInputCreator[];
14
+ readonly outputCreators?: BuildStepOutputCreator[];
15
+ readonly command: string;
16
+ readonly shell?: string;
17
+ constructor(ctx: BuildStepContext, { id, name, platforms, inputCreators, outputCreators, command, shell, }: {
18
+ id?: string;
19
+ name?: string;
20
+ platforms?: BuildPlatform[];
21
+ inputCreators?: BuildStepInputCreator[];
22
+ outputCreators?: BuildStepOutputCreator[];
23
+ command: string;
24
+ shell?: string;
25
+ });
26
+ createBuildStepFromFunctionCall({ id, callInputs, workingDirectory, shell, }: {
27
+ id?: string;
28
+ callInputs?: BuildFunctionCallInputs;
29
+ workingDirectory: string;
30
+ shell?: string;
31
+ }): BuildStep;
32
+ }
@@ -0,0 +1,36 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { BuildStep } from './BuildStep.js';
3
+ export class BuildFunction {
4
+ constructor(ctx, { id, name, platforms, inputCreators, outputCreators, command, shell, }) {
5
+ this.ctx = ctx;
6
+ this.id = id;
7
+ this.name = name;
8
+ this.platforms = platforms;
9
+ this.inputCreators = inputCreators;
10
+ this.outputCreators = outputCreators;
11
+ this.command = command;
12
+ this.shell = shell;
13
+ }
14
+ createBuildStepFromFunctionCall({ id, callInputs = {}, workingDirectory, shell, }) {
15
+ var _a, _b, _c;
16
+ const buildStepId = (_a = id !== null && id !== void 0 ? id : this.id) !== null && _a !== void 0 ? _a : uuidv4();
17
+ const inputs = (_b = this.inputCreators) === null || _b === void 0 ? void 0 : _b.map((inputCreator) => {
18
+ const input = inputCreator(buildStepId);
19
+ if (input.id in callInputs) {
20
+ input.set(callInputs[input.id]);
21
+ }
22
+ return input;
23
+ });
24
+ const outputs = (_c = this.outputCreators) === null || _c === void 0 ? void 0 : _c.map((outputCreator) => outputCreator(buildStepId));
25
+ return new BuildStep(this.ctx, {
26
+ id: buildStepId,
27
+ name: this.name,
28
+ command: this.command,
29
+ workingDirectory,
30
+ inputs,
31
+ outputs,
32
+ shell,
33
+ });
34
+ }
35
+ }
36
+ //# sourceMappingURL=BuildFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildFunction.js","sourceRoot":"","sources":["../src/BuildFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQ3C,MAAM,OAAO,aAAa;IASxB,YACmB,GAAqB,EACtC,EACE,EAAE,EACF,IAAI,EACJ,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,KAAK,GASN;QAjBgB,QAAG,GAAH,GAAG,CAAkB;QAmBtC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEM,+BAA+B,CAAC,EACrC,EAAE,EACF,UAAU,GAAG,EAAE,EACf,gBAAgB,EAChB,KAAK,GAMN;;QACC,MAAM,WAAW,GAAG,MAAA,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,IAAI,CAAC,EAAE,mCAAI,MAAM,EAAE,CAAC;QAE9C,MAAM,MAAM,GAAG,MAAA,IAAI,CAAC,aAAa,0CAAE,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;YACtD,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,EAAE,IAAI,UAAU,EAAE;gBAC1B,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;aACjC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAA,IAAI,CAAC,cAAc,0CAAE,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;QAExF,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE;YAC7B,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,gBAAgB;YAChB,MAAM;YACN,OAAO;YACP,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { v4 as uuidv4 } from 'uuid';\n\nimport { BuildPlatform } from './BuildPlatform.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepInputCreator } from './BuildStepInput.js';\nimport { BuildStepOutputCreator } from './BuildStepOutput.js';\n\nexport type BuildFunctionById = Record<string, BuildFunction>;\nexport type BuildFunctionCallInputs = Record<string, string>;\n\nexport class BuildFunction {\n public readonly id?: string;\n public readonly name?: string;\n public readonly platforms?: BuildPlatform[];\n public readonly inputCreators?: BuildStepInputCreator[];\n public readonly outputCreators?: BuildStepOutputCreator[];\n public readonly command: string;\n public readonly shell?: string;\n\n constructor(\n private readonly ctx: BuildStepContext,\n {\n id,\n name,\n platforms,\n inputCreators,\n outputCreators,\n command,\n shell,\n }: {\n id?: string;\n name?: string;\n platforms?: BuildPlatform[];\n inputCreators?: BuildStepInputCreator[];\n outputCreators?: BuildStepOutputCreator[];\n command: string;\n shell?: string;\n }\n ) {\n this.id = id;\n this.name = name;\n this.platforms = platforms;\n this.inputCreators = inputCreators;\n this.outputCreators = outputCreators;\n this.command = command;\n this.shell = shell;\n }\n\n public createBuildStepFromFunctionCall({\n id,\n callInputs = {},\n workingDirectory,\n shell,\n }: {\n id?: string;\n callInputs?: BuildFunctionCallInputs;\n workingDirectory: string;\n shell?: string;\n }): BuildStep {\n const buildStepId = id ?? this.id ?? uuidv4();\n\n const inputs = this.inputCreators?.map((inputCreator) => {\n const input = inputCreator(buildStepId);\n if (input.id in callInputs) {\n input.set(callInputs[input.id]);\n }\n return input;\n });\n const outputs = this.outputCreators?.map((outputCreator) => outputCreator(buildStepId));\n\n return new BuildStep(this.ctx, {\n id: buildStepId,\n name: this.name,\n command: this.command,\n workingDirectory,\n inputs,\n outputs,\n shell,\n });\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare enum BuildPlatform {
2
+ DARWIN = "darwin",
3
+ LINUX = "linux"
4
+ }
@@ -0,0 +1,6 @@
1
+ export var BuildPlatform;
2
+ (function (BuildPlatform) {
3
+ BuildPlatform["DARWIN"] = "darwin";
4
+ BuildPlatform["LINUX"] = "linux";
5
+ })(BuildPlatform || (BuildPlatform = {}));
6
+ //# sourceMappingURL=BuildPlatform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildPlatform.js","sourceRoot":"","sources":["../src/BuildPlatform.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,kCAAiB,CAAA;IACjB,gCAAe,CAAA;AACjB,CAAC,EAHW,aAAa,KAAb,aAAa,QAGxB","sourcesContent":["export enum BuildPlatform {\n DARWIN = 'darwin',\n LINUX = 'linux',\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { BuildStepContext } from './BuildStepContext.js';
2
+ export type BuildStepInputCreator = (stepId: string) => BuildStepInput;
2
3
  export declare class BuildStepInput {
3
4
  private readonly ctx;
4
5
  readonly id: string;
@@ -1,7 +1,7 @@
1
1
  import { BuildStepRuntimeError } from './errors/BuildStepRuntimeError.js';
2
2
  import { interpolateWithOutputs } from './utils/template.js';
3
3
  export class BuildStepInput {
4
- constructor(ctx, { id, stepId, defaultValue, required = false, }) {
4
+ constructor(ctx, { id, stepId, defaultValue, required = true, }) {
5
5
  this.ctx = ctx;
6
6
  this.id = id;
7
7
  this.stepId = stepId;