@expo/steps 1.0.0 → 1.0.8

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 (56) hide show
  1. package/LICENSE +1 -1
  2. package/dist_commonjs/BuildConfig.cjs +50 -19
  3. package/dist_commonjs/BuildConfig.d.ts +16 -5
  4. package/dist_commonjs/BuildConfig.js.map +1 -1
  5. package/dist_commonjs/BuildConfigParser.cjs +10 -10
  6. package/dist_commonjs/BuildConfigParser.d.ts +1 -2
  7. package/dist_commonjs/BuildConfigParser.js.map +1 -1
  8. package/dist_commonjs/BuildFunction.cjs +3 -0
  9. package/dist_commonjs/BuildFunction.d.ts +1 -0
  10. package/dist_commonjs/BuildFunction.js.map +1 -1
  11. package/dist_commonjs/BuildStep.cjs +3 -1
  12. package/dist_commonjs/BuildStep.js.map +1 -1
  13. package/dist_commonjs/BuildStepInput.cjs +10 -1
  14. package/dist_commonjs/BuildStepInput.d.ts +14 -11
  15. package/dist_commonjs/BuildStepInput.js.map +1 -1
  16. package/dist_commonjs/BuildStepOutput.cjs +1 -1
  17. package/dist_commonjs/BuildStepOutput.d.ts +10 -9
  18. package/dist_commonjs/BuildStepOutput.js.map +1 -1
  19. package/dist_commonjs/BuildWorkflowValidator.cjs +7 -0
  20. package/dist_commonjs/BuildWorkflowValidator.js.map +1 -1
  21. package/dist_commonjs/cli/cli.cjs +7 -0
  22. package/dist_commonjs/cli/cli.js.map +1 -1
  23. package/dist_commonjs/errors.cjs +3 -1
  24. package/dist_commonjs/errors.d.ts +1 -1
  25. package/dist_commonjs/errors.js.map +1 -1
  26. package/dist_commonjs/index.cjs +3 -1
  27. package/dist_commonjs/index.d.ts +1 -0
  28. package/dist_commonjs/index.js.map +1 -1
  29. package/dist_esm/BuildConfig.d.ts +16 -5
  30. package/dist_esm/BuildConfig.js +46 -17
  31. package/dist_esm/BuildConfig.js.map +1 -1
  32. package/dist_esm/BuildConfigParser.d.ts +1 -2
  33. package/dist_esm/BuildConfigParser.js +11 -11
  34. package/dist_esm/BuildConfigParser.js.map +1 -1
  35. package/dist_esm/BuildFunction.d.ts +1 -0
  36. package/dist_esm/BuildFunction.js +3 -0
  37. package/dist_esm/BuildFunction.js.map +1 -1
  38. package/dist_esm/BuildStep.js +3 -1
  39. package/dist_esm/BuildStep.js.map +1 -1
  40. package/dist_esm/BuildStepInput.d.ts +14 -11
  41. package/dist_esm/BuildStepInput.js +10 -1
  42. package/dist_esm/BuildStepInput.js.map +1 -1
  43. package/dist_esm/BuildStepOutput.d.ts +10 -9
  44. package/dist_esm/BuildStepOutput.js +1 -1
  45. package/dist_esm/BuildStepOutput.js.map +1 -1
  46. package/dist_esm/BuildWorkflowValidator.js +7 -0
  47. package/dist_esm/BuildWorkflowValidator.js.map +1 -1
  48. package/dist_esm/cli/cli.js +7 -0
  49. package/dist_esm/cli/cli.js.map +1 -1
  50. package/dist_esm/errors.d.ts +1 -1
  51. package/dist_esm/errors.js +1 -0
  52. package/dist_esm/errors.js.map +1 -1
  53. package/dist_esm/index.d.ts +1 -0
  54. package/dist_esm/index.js +1 -0
  55. package/dist_esm/index.js.map +1 -1
  56. package/package.json +2 -2
@@ -8,7 +8,7 @@ class BuildStepOutput {
8
8
  }
9
9
  constructor(
10
10
  // @ts-expect-error ctx is not used in this class but let's keep it here for consistency
11
- ctx, { id, stepDisplayName, required = true, }) {
11
+ ctx, { id, stepDisplayName, required = true }) {
12
12
  this.ctx = ctx;
13
13
  this.id = id;
14
14
  this.stepDisplayName = stepDisplayName;
@@ -1,22 +1,23 @@
1
1
  import { BuildStepContext } from './BuildStepContext.js';
2
2
  export type BuildStepOutputById = Record<string, BuildStepOutput>;
3
3
  export type BuildStepOutputProvider = (ctx: BuildStepContext, stepDisplayName: string) => BuildStepOutput;
4
+ interface BuildStepOutputProviderParams {
5
+ id: string;
6
+ required?: boolean;
7
+ }
8
+ interface BuildStepOutputParams extends BuildStepOutputProviderParams {
9
+ stepDisplayName: string;
10
+ }
4
11
  export declare class BuildStepOutput {
5
12
  private readonly ctx;
6
13
  readonly id: string;
7
14
  readonly stepDisplayName: string;
8
15
  readonly required: boolean;
9
16
  private _value?;
10
- static createProvider(params: {
11
- id: string;
12
- required?: boolean;
13
- }): BuildStepOutputProvider;
14
- constructor(ctx: BuildStepContext, { id, stepDisplayName, required, }: {
15
- id: string;
16
- stepDisplayName: string;
17
- required?: boolean;
18
- });
17
+ static createProvider(params: BuildStepOutputProviderParams): BuildStepOutputProvider;
18
+ constructor(ctx: BuildStepContext, { id, stepDisplayName, required }: BuildStepOutputParams);
19
19
  get value(): string | undefined;
20
20
  set(value: string | undefined): BuildStepOutput;
21
21
  }
22
22
  export declare function makeBuildStepOutputByIdMap(outputs?: BuildStepOutput[]): BuildStepOutputById;
23
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"BuildStepOutput.js","sourceRoot":"","sources":["../src/BuildStepOutput.ts"],"names":[],"mappings":";;;AACA,2CAAoD;AAQpD,MAAa,eAAe;IAOnB,MAAM,CAAC,cAAc,CAAC,MAG5B;QACC,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED;IACE,wFAAwF;IACvE,GAAqB,EACtC,EACE,EAAE,EACF,eAAe,EACf,QAAQ,GAAG,IAAI,GAC6C;QAL7C,QAAG,GAAH,GAAG,CAAkB;QAOtC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK;QACP,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;YAC9C,MAAM,IAAI,iCAAqB,CAC7B,qBAAqB,IAAI,CAAC,EAAE,eAAe,IAAI,CAAC,eAAe,mCAAmC,CACnG,CAAC;SACH;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,KAAyB;QAC3B,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE;YACxC,MAAM,IAAI,iCAAqB,CAC7B,qBAAqB,IAAI,CAAC,EAAE,eAAe,IAAI,CAAC,eAAe,gBAAgB,CAChF,CAAC;SACH;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA9CD,0CA8CC;AAED,SAAgB,0BAA0B,CAAC,OAA2B;IACpE,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,OAAO,EAAE,CAAC;KACX;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACpC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;QACxB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAyB,CAAC,CAAC;AAChC,CAAC;AARD,gEAQC","sourcesContent":["import { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepRuntimeError } from './errors.js';\n\nexport type BuildStepOutputById = Record<string, BuildStepOutput>;\nexport type BuildStepOutputProvider = (\n ctx: BuildStepContext,\n stepDisplayName: string\n) => BuildStepOutput;\n\nexport class BuildStepOutput {\n public readonly id: string;\n public readonly stepDisplayName: string;\n public readonly required: boolean;\n\n private _value?: string;\n\n public static createProvider(params: {\n id: string;\n required?: boolean;\n }): BuildStepOutputProvider {\n return (ctx, stepDisplayName) => new BuildStepOutput(ctx, { ...params, stepDisplayName });\n }\n\n constructor(\n // @ts-expect-error ctx is not used in this class but let's keep it here for consistency\n private readonly ctx: BuildStepContext,\n {\n id,\n stepDisplayName,\n required = true,\n }: { id: string; stepDisplayName: string; required?: boolean }\n ) {\n this.id = id;\n this.stepDisplayName = stepDisplayName;\n this.required = required;\n }\n\n get value(): string | undefined {\n if (this.required && this._value === undefined) {\n throw new BuildStepRuntimeError(\n `Output parameter \"${this.id}\" for step \"${this.stepDisplayName}\" is required but it was not set.`\n );\n }\n return this._value;\n }\n\n set(value: string | undefined): BuildStepOutput {\n if (this.required && value === undefined) {\n throw new BuildStepRuntimeError(\n `Output parameter \"${this.id}\" for step \"${this.stepDisplayName}\" is required.`\n );\n }\n this._value = value;\n return this;\n }\n}\n\nexport function makeBuildStepOutputByIdMap(outputs?: BuildStepOutput[]): BuildStepOutputById {\n if (outputs === undefined) {\n return {};\n }\n return outputs.reduce((acc, output) => {\n acc[output.id] = output;\n return acc;\n }, {} as BuildStepOutputById);\n}\n"]}
1
+ {"version":3,"file":"BuildStepOutput.js","sourceRoot":"","sources":["../src/BuildStepOutput.ts"],"names":[],"mappings":";;;AACA,2CAAoD;AAiBpD,MAAa,eAAe;IAOnB,MAAM,CAAC,cAAc,CAAC,MAAqC;QAChE,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED;IACE,wFAAwF;IACvE,GAAqB,EACtC,EAAE,EAAE,EAAE,eAAe,EAAE,QAAQ,GAAG,IAAI,EAAyB;QAD9C,QAAG,GAAH,GAAG,CAAkB;QAGtC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAW,KAAK;QACd,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;YAC9C,MAAM,IAAI,iCAAqB,CAC7B,qBAAqB,IAAI,CAAC,EAAE,eAAe,IAAI,CAAC,eAAe,mCAAmC,CACnG,CAAC;SACH;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,GAAG,CAAC,KAAyB;QAClC,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE;YACxC,MAAM,IAAI,iCAAqB,CAC7B,qBAAqB,IAAI,CAAC,EAAE,eAAe,IAAI,CAAC,eAAe,gBAAgB,CAChF,CAAC;SACH;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAvCD,0CAuCC;AAED,SAAgB,0BAA0B,CAAC,OAA2B;IACpE,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,OAAO,EAAE,CAAC;KACX;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACpC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;QACxB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAyB,CAAC,CAAC;AAChC,CAAC;AARD,gEAQC","sourcesContent":["import { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepRuntimeError } from './errors.js';\n\nexport type BuildStepOutputById = Record<string, BuildStepOutput>;\nexport type BuildStepOutputProvider = (\n ctx: BuildStepContext,\n stepDisplayName: string\n) => BuildStepOutput;\n\ninterface BuildStepOutputProviderParams {\n id: string;\n required?: boolean;\n}\n\ninterface BuildStepOutputParams extends BuildStepOutputProviderParams {\n stepDisplayName: string;\n}\n\nexport class BuildStepOutput {\n public readonly id: string;\n public readonly stepDisplayName: string;\n public readonly required: boolean;\n\n private _value?: string;\n\n public static createProvider(params: BuildStepOutputProviderParams): BuildStepOutputProvider {\n return (ctx, stepDisplayName) => new BuildStepOutput(ctx, { ...params, stepDisplayName });\n }\n\n constructor(\n // @ts-expect-error ctx is not used in this class but let's keep it here for consistency\n private readonly ctx: BuildStepContext,\n { id, stepDisplayName, required = true }: BuildStepOutputParams\n ) {\n this.id = id;\n this.stepDisplayName = stepDisplayName;\n this.required = required;\n }\n\n public get value(): string | undefined {\n if (this.required && this._value === undefined) {\n throw new BuildStepRuntimeError(\n `Output parameter \"${this.id}\" for step \"${this.stepDisplayName}\" is required but it was not set.`\n );\n }\n return this._value;\n }\n\n public set(value: string | undefined): BuildStepOutput {\n if (this.required && value === undefined) {\n throw new BuildStepRuntimeError(\n `Output parameter \"${this.id}\" for step \"${this.stepDisplayName}\" is required.`\n );\n }\n this._value = value;\n return this;\n }\n}\n\nexport function makeBuildStepOutputByIdMap(outputs?: BuildStepOutput[]): BuildStepOutputById {\n if (outputs === undefined) {\n return {};\n }\n return outputs.reduce((acc, output) => {\n acc[output.id] = output;\n return acc;\n }, {} as BuildStepOutputById);\n}\n"]}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BuildWorkflowValidator = void 0;
4
4
  const errors_js_1 = require("./errors.cjs");
5
5
  const duplicates_js_1 = require("./utils/expodash/duplicates.cjs");
6
+ const nullthrows_js_1 = require("./utils/nullthrows.cjs");
6
7
  const template_js_1 = require("./utils/template.cjs");
7
8
  class BuildWorkflowValidator {
8
9
  constructor(workflow) {
@@ -37,6 +38,12 @@ class BuildWorkflowValidator {
37
38
  if (currentStepInput.defaultValue === undefined) {
38
39
  continue;
39
40
  }
41
+ if (!currentStepInput.isValueOneOfAllowedValues()) {
42
+ const error = new errors_js_1.BuildConfigError(`Input parameter "${currentStepInput.id}" for step "${currentStep.displayName}" is set to "${currentStepInput.value}" which is not one of the allowed values: ${(0, nullthrows_js_1.nullthrows)(currentStepInput.allowedValues)
43
+ .map((i) => `"${i}"`)
44
+ .join(', ')}.`);
45
+ errors.push(error);
46
+ }
40
47
  const paths = (0, template_js_1.findOutputPaths)(currentStepInput.defaultValue);
41
48
  for (const { stepId: referencedStepId, outputId: referencedStepOutputId } of paths) {
42
49
  if (!(referencedStepId in visitedStepByStepId)) {
@@ -1 +1 @@
1
- {"version":3,"file":"BuildWorkflowValidator.js","sourceRoot":"","sources":["../src/BuildWorkflowValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BuildStep } from './BuildStep.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildConfigError, BuildWorkflowError } from './errors.js';\nimport { duplicates } from './utils/expodash/duplicates.js';\nimport { findOutputPaths } from './utils/template.js';\n\nexport class BuildWorkflowValidator {\n constructor(private readonly workflow: BuildWorkflow) {}\n\n public validate(): void {\n const errors: BuildConfigError[] = [];\n errors.push(...this.validateUniqueStepIds());\n errors.push(...this.validateInputs());\n if (errors.length !== 0) {\n throw new BuildWorkflowError('Build workflow is invalid.', errors);\n }\n }\n\n private validateUniqueStepIds(): BuildConfigError[] {\n const stepIds = this.workflow.buildSteps.map(({ id }) => id);\n const duplicatedStepIds = duplicates(stepIds);\n if (duplicatedStepIds.length === 0) {\n return [];\n } else {\n const error = new BuildConfigError(\n `Duplicated step IDs: ${duplicatedStepIds.map((i) => `\"${i}\"`).join(', ')}`\n );\n return [error];\n }\n }\n\n private validateInputs(): BuildConfigError[] {\n const errors: BuildConfigError[] = [];\n\n const allStepIds = new Set(this.workflow.buildSteps.map((s) => s.id));\n const visitedStepByStepId: Record<string, BuildStep> = {};\n for (const currentStep of this.workflow.buildSteps) {\n for (const currentStepInput of currentStep.inputs ?? []) {\n if (currentStepInput.defaultValue === undefined) {\n continue;\n }\n const paths = findOutputPaths(currentStepInput.defaultValue);\n for (const { stepId: referencedStepId, outputId: referencedStepOutputId } of paths) {\n if (!(referencedStepId in visitedStepByStepId)) {\n if (allStepIds.has(referencedStepId)) {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an output parameter from the future step \"${referencedStepId}\".`\n );\n errors.push(error);\n } else {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an output parameter from a non-existent step \"${referencedStepId}\".`\n );\n errors.push(error);\n }\n } else {\n if (!visitedStepByStepId[referencedStepId].hasOutputParameter(referencedStepOutputId)) {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an undefined output parameter \"${referencedStepOutputId}\" from step \"${referencedStepId}\".`\n );\n errors.push(error);\n }\n }\n }\n }\n visitedStepByStepId[currentStep.id] = currentStep;\n }\n\n return errors;\n }\n}\n"]}
1
+ {"version":3,"file":"BuildWorkflowValidator.js","sourceRoot":"","sources":["../src/BuildWorkflowValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BuildStep } from './BuildStep.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildConfigError, BuildWorkflowError } from './errors.js';\nimport { duplicates } from './utils/expodash/duplicates.js';\nimport { nullthrows } from './utils/nullthrows.js';\nimport { findOutputPaths } from './utils/template.js';\n\nexport class BuildWorkflowValidator {\n constructor(private readonly workflow: BuildWorkflow) {}\n\n public validate(): void {\n const errors: BuildConfigError[] = [];\n errors.push(...this.validateUniqueStepIds());\n errors.push(...this.validateInputs());\n if (errors.length !== 0) {\n throw new BuildWorkflowError('Build workflow is invalid.', errors);\n }\n }\n\n private validateUniqueStepIds(): BuildConfigError[] {\n const stepIds = this.workflow.buildSteps.map(({ id }) => id);\n const duplicatedStepIds = duplicates(stepIds);\n if (duplicatedStepIds.length === 0) {\n return [];\n } else {\n const error = new BuildConfigError(\n `Duplicated step IDs: ${duplicatedStepIds.map((i) => `\"${i}\"`).join(', ')}`\n );\n return [error];\n }\n }\n\n private validateInputs(): BuildConfigError[] {\n const errors: BuildConfigError[] = [];\n\n const allStepIds = new Set(this.workflow.buildSteps.map((s) => s.id));\n const visitedStepByStepId: Record<string, BuildStep> = {};\n for (const currentStep of this.workflow.buildSteps) {\n for (const currentStepInput of currentStep.inputs ?? []) {\n if (currentStepInput.defaultValue === undefined) {\n continue;\n }\n if (!currentStepInput.isValueOneOfAllowedValues()) {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${\n currentStep.displayName\n }\" is set to \"${\n currentStepInput.value\n }\" which is not one of the allowed values: ${nullthrows(currentStepInput.allowedValues)\n .map((i) => `\"${i}\"`)\n .join(', ')}.`\n );\n errors.push(error);\n }\n const paths = findOutputPaths(currentStepInput.defaultValue);\n for (const { stepId: referencedStepId, outputId: referencedStepOutputId } of paths) {\n if (!(referencedStepId in visitedStepByStepId)) {\n if (allStepIds.has(referencedStepId)) {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an output parameter from the future step \"${referencedStepId}\".`\n );\n errors.push(error);\n } else {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an output parameter from a non-existent step \"${referencedStepId}\".`\n );\n errors.push(error);\n }\n } else {\n if (!visitedStepByStepId[referencedStepId].hasOutputParameter(referencedStepOutputId)) {\n const error = new BuildConfigError(\n `Input parameter \"${currentStepInput.id}\" for step \"${currentStep.displayName}\" uses an expression that references an undefined output parameter \"${referencedStepOutputId}\" from step \"${referencedStepId}\".`\n );\n errors.push(error);\n }\n }\n }\n }\n visitedStepByStepId[currentStep.id] = currentStep;\n }\n\n return errors;\n }\n}\n"]}
@@ -8,6 +8,7 @@ const logger_1 = require("@expo/logger");
8
8
  const uuid_1 = require("uuid");
9
9
  const BuildConfigParser_js_1 = require("../BuildConfigParser.cjs");
10
10
  const BuildStepContext_js_1 = require("../BuildStepContext.cjs");
11
+ const errors_js_1 = require("../errors.cjs");
11
12
  const logger = (0, logger_1.createLogger)({
12
13
  name: 'steps-cli',
13
14
  level: 'info',
@@ -29,5 +30,11 @@ const configPath = path_1.default.resolve(process.cwd(), relativeConfigPath);
29
30
  const workingDirectory = path_1.default.resolve(process.cwd(), relativeWorkingDirectoryPath);
30
31
  runAsync(configPath, workingDirectory).catch((err) => {
31
32
  logger.error({ err }, 'Build failed');
33
+ if (err instanceof errors_js_1.BuildWorkflowError) {
34
+ logger.error('Failed to parse the custom build config file.');
35
+ for (const detailedErr of err.errors) {
36
+ logger.error({ err: detailedErr });
37
+ }
38
+ }
32
39
  });
33
40
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB,yCAA4C;AAC5C,+BAAoC;AAEpC,kEAA4D;AAC5D,gEAA0D;AAE1D,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC;IAC1B,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,MAAM;CACd,CAAC,CAAC;AAEH,KAAK,UAAU,QAAQ,CAAC,UAAkB,EAAE,gBAAwB;IAClE,MAAM,WAAW,GAAG,IAAA,SAAM,GAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,sCAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,IAAI,wCAAiB,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC3C,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3C,MAAM,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErD,IAAI,CAAC,kBAAkB,IAAI,CAAC,4BAA4B,EAAE;IACxD,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACnE,MAAM,gBAAgB,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC;AAEnF,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC","sourcesContent":["import path from 'path';\n\nimport { createLogger } from '@expo/logger';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BuildConfigParser } from '../BuildConfigParser.js';\nimport { BuildStepContext } from '../BuildStepContext.js';\n\nconst logger = createLogger({\n name: 'steps-cli',\n level: 'info',\n});\n\nasync function runAsync(configPath: string, workingDirectory: string): Promise<void> {\n const fakeBuildId = uuidv4();\n const ctx = new BuildStepContext(fakeBuildId, logger, false, workingDirectory);\n const parser = new BuildConfigParser(ctx, { configPath });\n const workflow = await parser.parseAsync();\n await workflow.executeAsync();\n}\n\nconst relativeConfigPath = process.argv[2];\nconst relativeWorkingDirectoryPath = process.argv[3];\n\nif (!relativeConfigPath && !relativeWorkingDirectoryPath) {\n console.error('Usage: yarn cli config.yml path/to/working/directory');\n process.exit(1);\n}\n\nconst configPath = path.resolve(process.cwd(), relativeConfigPath);\nconst workingDirectory = path.resolve(process.cwd(), relativeWorkingDirectoryPath);\n\nrunAsync(configPath, workingDirectory).catch((err) => {\n logger.error({ err }, 'Build failed');\n});\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB,yCAA4C;AAC5C,+BAAoC;AAEpC,kEAA4D;AAC5D,gEAA0D;AAC1D,4CAAkD;AAElD,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC;IAC1B,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,MAAM;CACd,CAAC,CAAC;AAEH,KAAK,UAAU,QAAQ,CAAC,UAAkB,EAAE,gBAAwB;IAClE,MAAM,WAAW,GAAG,IAAA,SAAM,GAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,sCAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,IAAI,wCAAiB,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC3C,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3C,MAAM,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErD,IAAI,CAAC,kBAAkB,IAAI,CAAC,4BAA4B,EAAE;IACxD,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACnE,MAAM,gBAAgB,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC;AAEnF,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IACtC,IAAI,GAAG,YAAY,8BAAkB,EAAE;QACrC,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC9D,KAAK,MAAM,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE;YACpC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;SACpC;KACF;AACH,CAAC,CAAC,CAAC","sourcesContent":["import path from 'path';\n\nimport { createLogger } from '@expo/logger';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BuildConfigParser } from '../BuildConfigParser.js';\nimport { BuildStepContext } from '../BuildStepContext.js';\nimport { BuildWorkflowError } from '../errors.js';\n\nconst logger = createLogger({\n name: 'steps-cli',\n level: 'info',\n});\n\nasync function runAsync(configPath: string, workingDirectory: string): Promise<void> {\n const fakeBuildId = uuidv4();\n const ctx = new BuildStepContext(fakeBuildId, logger, false, workingDirectory);\n const parser = new BuildConfigParser(ctx, { configPath });\n const workflow = await parser.parseAsync();\n await workflow.executeAsync();\n}\n\nconst relativeConfigPath = process.argv[2];\nconst relativeWorkingDirectoryPath = process.argv[3];\n\nif (!relativeConfigPath && !relativeWorkingDirectoryPath) {\n console.error('Usage: yarn cli config.yml path/to/working/directory');\n process.exit(1);\n}\n\nconst configPath = path.resolve(process.cwd(), relativeConfigPath);\nconst workingDirectory = path.resolve(process.cwd(), relativeWorkingDirectoryPath);\n\nrunAsync(configPath, workingDirectory).catch((err) => {\n logger.error({ err }, 'Build failed');\n if (err instanceof BuildWorkflowError) {\n logger.error('Failed to parse the custom build config file.');\n for (const detailedErr of err.errors) {\n logger.error({ err: detailedErr });\n }\n }\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BuildWorkflowError = exports.BuildStepRuntimeError = exports.BuildInternalError = exports.BuildConfigError = void 0;
3
+ exports.BuildWorkflowError = exports.BuildStepRuntimeError = exports.BuildInternalError = exports.BuildConfigYAMLError = exports.BuildConfigError = void 0;
4
4
  class UserError extends Error {
5
5
  constructor(message, extra) {
6
6
  var _a;
@@ -13,6 +13,8 @@ class UserError extends Error {
13
13
  class BuildConfigError extends UserError {
14
14
  }
15
15
  exports.BuildConfigError = BuildConfigError;
16
+ var yaml_1 = require("yaml");
17
+ Object.defineProperty(exports, "BuildConfigYAMLError", { enumerable: true, get: function () { return yaml_1.YAMLParseError; } });
16
18
  class BuildInternalError extends Error {
17
19
  }
18
20
  exports.BuildInternalError = BuildInternalError;
@@ -9,6 +9,7 @@ declare abstract class UserError extends Error {
9
9
  }
10
10
  export declare class BuildConfigError extends UserError {
11
11
  }
12
+ export { YAMLParseError as BuildConfigYAMLError } from 'yaml';
12
13
  export declare class BuildInternalError extends Error {
13
14
  }
14
15
  export declare class BuildStepRuntimeError extends UserError {
@@ -21,4 +22,3 @@ export declare class BuildWorkflowError extends UserError {
21
22
  cause?: Error;
22
23
  });
23
24
  }
24
- export {};
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAe,SAAU,SAAQ,KAAK;IAIpC,YAC2B,OAAe,EACxC,KAGC;;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QANU,YAAO,GAAP,OAAO,CAAQ;QAOxC,IAAI,CAAC,QAAQ,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,mCAAI,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,CAAC;IAC5B,CAAC;CACF;AAED,MAAa,gBAAiB,SAAQ,SAAS;CAAG;AAAlD,4CAAkD;AAElD,MAAa,kBAAmB,SAAQ,KAAK;CAAG;AAAhD,gDAAgD;AAEhD,MAAa,qBAAsB,SAAQ,SAAS;CAAG;AAAvD,sDAAuD;AAEvD,MAAa,kBAAmB,SAAQ,SAAS;IAC/C,YAC2B,OAAe,EACxB,MAA0B,EAC1C,KAGC;QAED,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAPG,YAAO,GAAP,OAAO,CAAQ;QACxB,WAAM,GAAN,MAAM,CAAoB;IAO5C,CAAC;CACF;AAXD,gDAWC","sourcesContent":["abstract class UserError extends Error {\n public readonly cause?: Error;\n public readonly metadata: object;\n\n constructor(\n public override readonly message: string,\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message);\n this.metadata = extra?.cause ?? {};\n this.cause = extra?.cause;\n }\n}\n\nexport class BuildConfigError extends UserError {}\n\nexport class BuildInternalError extends Error {}\n\nexport class BuildStepRuntimeError extends UserError {}\n\nexport class BuildWorkflowError extends UserError {\n constructor(\n public override readonly message: string,\n public readonly errors: BuildConfigError[],\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message, extra);\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAe,SAAU,SAAQ,KAAK;IAIpC,YAC2B,OAAe,EACxC,KAGC;;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QANU,YAAO,GAAP,OAAO,CAAQ;QAOxC,IAAI,CAAC,QAAQ,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,mCAAI,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,CAAC;IAC5B,CAAC;CACF;AAED,MAAa,gBAAiB,SAAQ,SAAS;CAAG;AAAlD,4CAAkD;AAElD,6BAA8D;AAArD,4GAAA,cAAc,OAAwB;AAE/C,MAAa,kBAAmB,SAAQ,KAAK;CAAG;AAAhD,gDAAgD;AAEhD,MAAa,qBAAsB,SAAQ,SAAS;CAAG;AAAvD,sDAAuD;AAEvD,MAAa,kBAAmB,SAAQ,SAAS;IAC/C,YAC2B,OAAe,EACxB,MAA0B,EAC1C,KAGC;QAED,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAPG,YAAO,GAAP,OAAO,CAAQ;QACxB,WAAM,GAAN,MAAM,CAAoB;IAO5C,CAAC;CACF;AAXD,gDAWC","sourcesContent":["abstract class UserError extends Error {\n public readonly cause?: Error;\n public readonly metadata: object;\n\n constructor(\n public override readonly message: string,\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message);\n this.metadata = extra?.cause ?? {};\n this.cause = extra?.cause;\n }\n}\n\nexport class BuildConfigError extends UserError {}\n\nexport { YAMLParseError as BuildConfigYAMLError } from 'yaml';\n\nexport class BuildInternalError extends Error {}\n\nexport class BuildStepRuntimeError extends UserError {}\n\nexport class BuildWorkflowError extends UserError {\n constructor(\n public override readonly message: string,\n public readonly errors: BuildConfigError[],\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message, extra);\n }\n}\n"]}
@@ -23,7 +23,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.errors = exports.BuildWorkflow = exports.BuildStepContext = exports.BuildStepOutput = exports.BuildStepInput = exports.BuildFunction = exports.BuildConfigParser = void 0;
26
+ exports.errors = exports.BuildWorkflow = exports.BuildStepContext = exports.BuildStepOutput = exports.BuildStepInput = exports.BuildFunction = exports.BuildConfigParser = exports.readAndValidateBuildConfigAsync = void 0;
27
+ var BuildConfig_js_1 = require("./BuildConfig.cjs");
28
+ Object.defineProperty(exports, "readAndValidateBuildConfigAsync", { enumerable: true, get: function () { return BuildConfig_js_1.readAndValidateBuildConfigAsync; } });
27
29
  var BuildConfigParser_js_1 = require("./BuildConfigParser.cjs");
28
30
  Object.defineProperty(exports, "BuildConfigParser", { enumerable: true, get: function () { return BuildConfigParser_js_1.BuildConfigParser; } });
29
31
  var BuildFunction_js_1 = require("./BuildFunction.cjs");
@@ -1,3 +1,4 @@
1
+ export { readAndValidateBuildConfigAsync } from './BuildConfig.js';
1
2
  export { BuildConfigParser } from './BuildConfigParser.js';
2
3
  export { BuildFunction } from './BuildFunction.js';
3
4
  export { BuildStepInput } from './BuildStepInput.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+DAA2D;AAAlD,yHAAA,iBAAiB,OAAA;AAC1B,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,yDAAqD;AAA5C,mHAAA,cAAc,OAAA;AACvB,2DAAuD;AAA9C,qHAAA,eAAe,OAAA;AACxB,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,sDAAsC","sourcesContent":["export { BuildConfigParser } from './BuildConfigParser.js';\nexport { BuildFunction } from './BuildFunction.js';\nexport { BuildStepInput } from './BuildStepInput.js';\nexport { BuildStepOutput } from './BuildStepOutput.js';\nexport { BuildStepContext } from './BuildStepContext.js';\nexport { BuildWorkflow } from './BuildWorkflow.js';\nexport * as errors from './errors.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAmE;AAA1D,iIAAA,+BAA+B,OAAA;AACxC,+DAA2D;AAAlD,yHAAA,iBAAiB,OAAA;AAC1B,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,yDAAqD;AAA5C,mHAAA,cAAc,OAAA;AACvB,2DAAuD;AAA9C,qHAAA,eAAe,OAAA;AACxB,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,sDAAsC","sourcesContent":["export { readAndValidateBuildConfigAsync } from './BuildConfig.js';\nexport { BuildConfigParser } from './BuildConfigParser.js';\nexport { BuildFunction } from './BuildFunction.js';\nexport { BuildStepInput } from './BuildStepInput.js';\nexport { BuildStepOutput } from './BuildStepOutput.js';\nexport { BuildStepContext } from './BuildStepContext.js';\nexport { BuildWorkflow } from './BuildWorkflow.js';\nexport * as errors from './errors.js';\n"]}
@@ -29,7 +29,10 @@ export type BuildFunctionCallConfig = {
29
29
  shell?: string;
30
30
  };
31
31
  export type BuildStepInputs = Record<string, string>;
32
- export type BuildStepOutputs = BuildInputOutputParameters;
32
+ export type BuildStepOutputs = (string | {
33
+ name: string;
34
+ required?: boolean;
35
+ })[];
33
36
  export interface BuildFunctionConfig {
34
37
  inputs?: BuildFunctionInputs;
35
38
  outputs?: BuildFunctionOutputs;
@@ -38,15 +41,23 @@ export interface BuildFunctionConfig {
38
41
  shell?: string;
39
42
  command: string;
40
43
  }
41
- export type BuildFunctionInputs = BuildInputOutputParameters;
42
- export type BuildFunctionOutputs = BuildInputOutputParameters;
43
- export type BuildInputOutputParameters = (string | {
44
+ export type BuildFunctionInputs = (string | {
44
45
  name: string;
46
+ defaultValue?: string;
47
+ allowedValues?: string[];
45
48
  required?: boolean;
46
49
  })[];
50
+ export type BuildFunctionOutputs = BuildStepOutputs;
47
51
  export declare const BuildConfigSchema: Joi.ObjectSchema<BuildConfig>;
52
+ interface BuildConfigValidationParams {
53
+ externalFunctionIds?: string[];
54
+ skipNamespacedFunctionsCheck?: boolean;
55
+ }
56
+ export declare function readAndValidateBuildConfigAsync(configPath: string, params?: BuildConfigValidationParams): Promise<BuildConfig>;
57
+ export declare function readRawBuildConfigAsync(configPath: string): Promise<any>;
58
+ export declare function validateBuildConfig(rawConfig: object, params: BuildConfigValidationParams): BuildConfig;
48
59
  export declare function isBuildStepCommandRun(step: BuildStepConfig): step is BuildStepCommandRun;
49
60
  export declare function isBuildStepBareCommandRun(step: BuildStepConfig): step is BuildStepBareCommandRun;
50
61
  export declare function isBuildStepFunctionCall(step: BuildStepConfig): step is BuildStepFunctionCall;
51
62
  export declare function isBuildStepBareFunctionCall(step: BuildStepConfig): step is BuildStepBareFunctionCall;
52
- export declare function validateBuildConfig(rawConfig: object, externalFunctionIds: string[]): BuildConfig;
63
+ export {};
@@ -1,8 +1,26 @@
1
1
  import assert from 'assert';
2
+ import fs from 'fs/promises';
2
3
  import Joi from 'joi';
4
+ import YAML from 'yaml';
3
5
  import { BuildConfigError } from './errors.js';
4
6
  import { BuildPlatform } from './BuildPlatform.js';
5
- const BuildInputOutputParametersSchema = Joi.array().items(Joi.alternatives().try(Joi.string().required(), Joi.object({
7
+ import { BuildFunction } from './BuildFunction.js';
8
+ const BuildFunctionInputsSchema = Joi.array().items(Joi.alternatives().try(Joi.string().required(), Joi.object({
9
+ name: Joi.string().required(),
10
+ defaultValue: Joi.alternatives().conditional('allowedValues', {
11
+ is: Joi.exist(),
12
+ then: Joi.string()
13
+ .valid(Joi.in('allowedValues'))
14
+ .messages({ 'any.only': '{{#label}} must be one of allowed values' }),
15
+ otherwise: Joi.string(),
16
+ }),
17
+ allowedValues: Joi.array().items(Joi.string()),
18
+ required: Joi.boolean(),
19
+ })
20
+ .rename('allowed_values', 'allowedValues')
21
+ .rename('default_value', 'defaultValue')
22
+ .required()));
23
+ const BuildStepOutputsSchema = Joi.array().items(Joi.alternatives().try(Joi.string().required(), Joi.object({
6
24
  name: Joi.string().required(),
7
25
  required: Joi.boolean(),
8
26
  }).required()));
@@ -20,7 +38,7 @@ const BuildStepConfigSchema = Joi.any()
20
38
  .when(Joi.object({ run: Joi.object().unknown().required() }), {
21
39
  then: Joi.object({
22
40
  run: BuildFunctionCallSchema.keys({
23
- outputs: BuildInputOutputParametersSchema,
41
+ outputs: BuildStepOutputsSchema,
24
42
  command: Joi.string().required(),
25
43
  }),
26
44
  }),
@@ -36,8 +54,8 @@ const BuildStepConfigSchema = Joi.any()
36
54
  const BuildFunctionConfigSchema = Joi.object({
37
55
  name: Joi.string(),
38
56
  platforms: Joi.string().allow(...Object.values(BuildPlatform)),
39
- inputs: BuildInputOutputParametersSchema,
40
- outputs: BuildInputOutputParametersSchema,
57
+ inputs: BuildFunctionInputsSchema,
58
+ outputs: BuildStepOutputsSchema,
41
59
  command: Joi.string().required(),
42
60
  shell: Joi.string(),
43
61
  });
@@ -52,19 +70,15 @@ export const BuildConfigSchema = Joi.object({
52
70
  .required()
53
71
  .disallow('run'), BuildFunctionConfigSchema.required()),
54
72
  }).required();
55
- export function isBuildStepCommandRun(step) {
56
- return typeof step === 'object' && typeof step.run === 'object';
57
- }
58
- export function isBuildStepBareCommandRun(step) {
59
- return typeof step === 'object' && typeof step.run === 'string';
73
+ export async function readAndValidateBuildConfigAsync(configPath, params = {}) {
74
+ const rawConfig = await readRawBuildConfigAsync(configPath);
75
+ return validateBuildConfig(rawConfig, params);
60
76
  }
61
- export function isBuildStepFunctionCall(step) {
62
- return typeof step === 'object' && !('run' in step);
63
- }
64
- export function isBuildStepBareFunctionCall(step) {
65
- return typeof step === 'string';
77
+ export async function readRawBuildConfigAsync(configPath) {
78
+ const contents = await fs.readFile(configPath, 'utf-8');
79
+ return YAML.parse(contents);
66
80
  }
67
- export function validateBuildConfig(rawConfig, externalFunctionIds) {
81
+ export function validateBuildConfig(rawConfig, params) {
68
82
  const { error, value: buildConfig } = BuildConfigSchema.validate(rawConfig, {
69
83
  allowUnknown: false,
70
84
  abortEarly: false,
@@ -73,10 +87,22 @@ export function validateBuildConfig(rawConfig, externalFunctionIds) {
73
87
  const errorMessage = error.details.map(({ message }) => message).join(', ');
74
88
  throw new BuildConfigError(errorMessage, { cause: error });
75
89
  }
76
- validateAllFunctionsExist(buildConfig, externalFunctionIds);
90
+ validateAllFunctionsExist(buildConfig, params);
77
91
  return buildConfig;
78
92
  }
79
- function validateAllFunctionsExist(config, externalFunctionIds) {
93
+ export function isBuildStepCommandRun(step) {
94
+ return typeof step === 'object' && typeof step.run === 'object';
95
+ }
96
+ export function isBuildStepBareCommandRun(step) {
97
+ return typeof step === 'object' && typeof step.run === 'string';
98
+ }
99
+ export function isBuildStepFunctionCall(step) {
100
+ return typeof step === 'object' && !('run' in step);
101
+ }
102
+ export function isBuildStepBareFunctionCall(step) {
103
+ return typeof step === 'string';
104
+ }
105
+ function validateAllFunctionsExist(config, { externalFunctionIds = [], skipNamespacedFunctionsCheck } = {}) {
80
106
  const calledFunctionsSet = new Set();
81
107
  for (const step of config.build.steps) {
82
108
  if (typeof step === 'string') {
@@ -92,6 +118,9 @@ function validateAllFunctionsExist(config, externalFunctionIds) {
92
118
  const externalFunctionIdsSet = new Set(externalFunctionIds);
93
119
  const nonExistentFunctions = calledFunctions.filter((calledFunction) => {
94
120
  var _a;
121
+ if (BuildFunction.isFulldIdNamespaced(calledFunction) && skipNamespacedFunctionsCheck) {
122
+ return false;
123
+ }
95
124
  return (!(calledFunction in ((_a = config.functions) !== null && _a !== void 0 ? _a : {})) && !externalFunctionIdsSet.has(calledFunction));
96
125
  });
97
126
  if (nonExistentFunctions.length > 0) {
@@ -1 +1 @@
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.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 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 BuildFunctionConfigSchema = Joi.object({\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()\n .pattern(/^[\\w-]+$/, 'function names')\n .min(1)\n .required()\n .disallow('run'),\n BuildFunctionConfigSchema.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, externalFunctionIds: string[]): 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, externalFunctionIds);\n return buildConfig;\n}\n\nfunction validateAllFunctionsExist(config: BuildConfig, externalFunctionIds: string[]): 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 externalFunctionIdsSet = new Set(externalFunctionIds);\n const nonExistentFunctions = calledFunctions.filter((calledFunction) => {\n return (\n !(calledFunction in (config.functions ?? {})) && !externalFunctionIdsSet.has(calledFunction)\n );\n });\n if (nonExistentFunctions.length > 0) {\n throw new BuildConfigError(\n `Calling non-existent functions: ${nonExistentFunctions.map((f) => `\"${f}\"`).join(', ')}.`\n );\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';\nimport fs from 'fs/promises';\n\nimport Joi from 'joi';\nimport YAML from 'yaml';\n\nimport { BuildConfigError } from './errors.js';\nimport { BuildPlatform } from './BuildPlatform.js';\nimport { BuildFunction } from './BuildFunction.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 = (\n | string\n | {\n name: string;\n required?: boolean;\n }\n)[];\n\nexport interface BuildFunctionConfig {\n inputs?: BuildFunctionInputs;\n outputs?: BuildFunctionOutputs;\n name?: string;\n platforms?: BuildPlatform[];\n shell?: string;\n command: string;\n}\n\nexport type BuildFunctionInputs = (\n | string\n | {\n name: string;\n defaultValue?: string;\n allowedValues?: string[];\n required?: boolean;\n }\n)[];\nexport type BuildFunctionOutputs = BuildStepOutputs;\n\nconst BuildFunctionInputsSchema = Joi.array().items(\n Joi.alternatives().try(\n Joi.string().required(),\n Joi.object({\n name: Joi.string().required(),\n defaultValue: Joi.alternatives().conditional('allowedValues', {\n is: Joi.exist(),\n then: Joi.string()\n .valid(Joi.in('allowedValues'))\n .messages({ 'any.only': '{{#label}} must be one of allowed values' }),\n otherwise: Joi.string(),\n }),\n allowedValues: Joi.array().items(Joi.string()),\n required: Joi.boolean(),\n })\n .rename('allowed_values', 'allowedValues')\n .rename('default_value', 'defaultValue')\n .required()\n )\n);\n\nconst BuildStepOutputsSchema = 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: BuildStepOutputsSchema,\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 BuildFunctionConfigSchema = Joi.object({\n name: Joi.string(),\n platforms: Joi.string().allow(...Object.values(BuildPlatform)),\n inputs: BuildFunctionInputsSchema,\n outputs: BuildStepOutputsSchema,\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()\n .pattern(/^[\\w-]+$/, 'function names')\n .min(1)\n .required()\n .disallow('run'),\n BuildFunctionConfigSchema.required()\n ),\n}).required();\n\ninterface BuildConfigValidationParams {\n externalFunctionIds?: string[];\n skipNamespacedFunctionsCheck?: boolean;\n}\n\nexport async function readAndValidateBuildConfigAsync(\n configPath: string,\n params: BuildConfigValidationParams = {}\n): Promise<BuildConfig> {\n const rawConfig = await readRawBuildConfigAsync(configPath);\n return validateBuildConfig(rawConfig, params);\n}\n\nexport async function readRawBuildConfigAsync(configPath: string): Promise<any> {\n const contents = await fs.readFile(configPath, 'utf-8');\n return YAML.parse(contents);\n}\n\nexport function validateBuildConfig(\n rawConfig: object,\n params: BuildConfigValidationParams\n): 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, params);\n return buildConfig;\n}\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\nfunction validateAllFunctionsExist(\n config: BuildConfig,\n { externalFunctionIds = [], skipNamespacedFunctionsCheck }: BuildConfigValidationParams = {}\n): 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 externalFunctionIdsSet = new Set(externalFunctionIds);\n const nonExistentFunctions = calledFunctions.filter((calledFunction) => {\n if (BuildFunction.isFulldIdNamespaced(calledFunction) && skipNamespacedFunctionsCheck) {\n return false;\n }\n return (\n !(calledFunction in (config.functions ?? {})) && !externalFunctionIdsSet.has(calledFunction)\n );\n });\n if (nonExistentFunctions.length > 0) {\n throw new BuildConfigError(\n `Calling non-existent functions: ${nonExistentFunctions.map((f) => `\"${f}\"`).join(', ')}.`\n );\n }\n}\n"]}
@@ -10,7 +10,6 @@ export declare class BuildConfigParser {
10
10
  externalFunctions?: BuildFunction[];
11
11
  });
12
12
  parseAsync(): Promise<BuildWorkflow>;
13
- private readRawConfigAsync;
14
13
  private createBuildStepFromConfig;
15
14
  private createBuildStepFromBuildStepCommandRun;
16
15
  private createBuildStepFromBuildStepBareCommandRun;
@@ -24,5 +23,5 @@ export declare class BuildConfigParser {
24
23
  private createBuildStepOutputProvidersFromBuildFunctionOutputs;
25
24
  private mergeBuildFunctionsWithExternal;
26
25
  private validateExternalFunctions;
27
- private getUniqueExternalFunctionIds;
26
+ private getExternalFunctionFullIds;
28
27
  }
@@ -1,7 +1,5 @@
1
1
  import assert from 'assert';
2
- import fs from 'fs/promises';
3
- import YAML from 'yaml';
4
- import { isBuildStepBareCommandRun, isBuildStepBareFunctionCall, isBuildStepCommandRun, validateBuildConfig, } from './BuildConfig.js';
2
+ import { isBuildStepBareCommandRun, isBuildStepBareFunctionCall, isBuildStepCommandRun, readAndValidateBuildConfigAsync, } from './BuildConfig.js';
5
3
  import { BuildFunction } from './BuildFunction.js';
6
4
  import { BuildStep } from './BuildStep.js';
7
5
  import { BuildStepInput } from './BuildStepInput.js';
@@ -19,8 +17,9 @@ export class BuildConfigParser {
19
17
  this.externalFunctions = externalFunctions;
20
18
  }
21
19
  async parseAsync() {
22
- const rawConfig = await this.readRawConfigAsync();
23
- const config = validateBuildConfig(rawConfig, this.getUniqueExternalFunctionIds());
20
+ const config = await readAndValidateBuildConfigAsync(this.configPath, {
21
+ externalFunctionIds: this.getExternalFunctionFullIds(),
22
+ });
24
23
  const configBuildFunctions = this.createBuildFunctionsFromConfig(config.functions);
25
24
  const buildFunctions = this.mergeBuildFunctionsWithExternal(configBuildFunctions, this.externalFunctions);
26
25
  const buildSteps = config.build.steps.map((stepConfig) => this.createBuildStepFromConfig(stepConfig, buildFunctions));
@@ -28,10 +27,6 @@ export class BuildConfigParser {
28
27
  new BuildWorkflowValidator(workflow).validate();
29
28
  return workflow;
30
29
  }
31
- async readRawConfigAsync() {
32
- const contents = await fs.readFile(this.configPath, 'utf-8');
33
- return YAML.parse(contents);
34
- }
35
30
  createBuildStepFromConfig(buildStepConfig, buildFunctions) {
36
31
  if (isBuildStepCommandRun(buildStepConfig)) {
37
32
  return this.createBuildStepFromBuildStepCommandRun(buildStepConfig);
@@ -122,7 +117,12 @@ export class BuildConfigParser {
122
117
  var _a;
123
118
  return typeof entry === 'string'
124
119
  ? BuildStepInput.createProvider({ id: entry })
125
- : BuildStepInput.createProvider({ id: entry.name, required: (_a = entry.required) !== null && _a !== void 0 ? _a : true });
120
+ : BuildStepInput.createProvider({
121
+ id: entry.name,
122
+ required: (_a = entry.required) !== null && _a !== void 0 ? _a : true,
123
+ defaultValue: entry.defaultValue,
124
+ allowedValues: entry.allowedValues,
125
+ });
126
126
  });
127
127
  }
128
128
  createBuildStepOutputsFromDefinition(buildStepOutputs, stepDisplayName) {
@@ -172,7 +172,7 @@ export class BuildConfigParser {
172
172
  .map((id) => `"${id}"`)
173
173
  .join(', ')}`);
174
174
  }
175
- getUniqueExternalFunctionIds() {
175
+ getExternalFunctionFullIds() {
176
176
  if (this.externalFunctions === undefined) {
177
177
  return [];
178
178
  }
@@ -1 +1 @@
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';\n\nimport YAML from 'yaml';\n\nimport {\n BuildConfig,\n BuildFunctionConfig,\n BuildFunctionInputs,\n BuildFunctionOutputs,\n BuildStepBareCommandRun,\n BuildStepBareFunctionCall,\n BuildStepCommandRun,\n BuildStepConfig,\n BuildStepFunctionCall,\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, BuildStepInputProvider } from './BuildStepInput.js';\nimport { BuildStepOutput, BuildStepOutputProvider } from './BuildStepOutput.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildWorkflowValidator } from './BuildWorkflowValidator.js';\nimport { BuildStepRuntimeError } from './errors.js';\nimport { duplicates } from './utils/expodash/duplicates.js';\nimport { uniq } from './utils/expodash/uniq.js';\n\nexport class BuildConfigParser {\n private readonly configPath: string;\n private readonly externalFunctions?: BuildFunction[];\n\n constructor(\n private readonly ctx: BuildStepContext,\n { configPath, externalFunctions }: { configPath: string; externalFunctions?: BuildFunction[] }\n ) {\n this.validateExternalFunctions(externalFunctions);\n\n this.configPath = configPath;\n this.externalFunctions = externalFunctions;\n }\n\n public async parseAsync(): Promise<BuildWorkflow> {\n const rawConfig = await this.readRawConfigAsync();\n const config = validateBuildConfig(rawConfig, this.getUniqueExternalFunctionIds());\n const configBuildFunctions = this.createBuildFunctionsFromConfig(config.functions);\n const buildFunctions = this.mergeBuildFunctionsWithExternal(\n configBuildFunctions,\n this.externalFunctions\n );\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 return this.createBuildStepFromBuildStepCommandRun(buildStepConfig);\n } else if (isBuildStepBareCommandRun(buildStepConfig)) {\n return this.createBuildStepFromBuildStepBareCommandRun(buildStepConfig);\n } else if (isBuildStepBareFunctionCall(buildStepConfig)) {\n return this.createBuildStepFromBuildStepBareFunctionCall(buildFunctions, buildStepConfig);\n } else {\n return this.createBuildStepFromBuildStepFunctionCall(buildFunctions, buildStepConfig);\n }\n }\n\n private createBuildStepFromBuildStepCommandRun({ run }: BuildStepCommandRun): BuildStep {\n const {\n id: maybeId,\n inputs: inputsConfig,\n outputs: outputsConfig,\n name,\n workingDirectory,\n shell,\n command,\n } = run;\n const id = BuildStep.getNewId(maybeId);\n const displayName = BuildStep.getDisplayName({ id, name, command });\n const inputs =\n inputsConfig && this.createBuildStepInputsFromDefinition(inputsConfig, displayName);\n const outputs =\n outputsConfig && this.createBuildStepOutputsFromDefinition(outputsConfig, displayName);\n return new BuildStep(this.ctx, {\n id,\n inputs,\n outputs,\n name,\n displayName,\n workingDirectory,\n shell,\n command,\n });\n }\n\n private createBuildStepFromBuildStepBareCommandRun({\n run: command,\n }: BuildStepBareCommandRun): BuildStep {\n const id = BuildStep.getNewId();\n const displayName = BuildStep.getDisplayName({ id, command });\n return new BuildStep(this.ctx, {\n id,\n displayName,\n command,\n });\n }\n\n private createBuildStepFromBuildStepBareFunctionCall(\n buildFunctions: BuildFunctionById,\n functionId: BuildStepBareFunctionCall\n ): BuildStep {\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall(this.ctx);\n }\n\n private createBuildStepFromBuildStepFunctionCall(\n buildFunctions: BuildFunctionById,\n buildStepFunctionCall: BuildStepFunctionCall\n ): BuildStep {\n const keys = Object.keys(buildStepFunctionCall);\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 = buildStepFunctionCall[functionId];\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall(this.ctx, {\n id: buildFunctionCallConfig.id,\n name: buildFunctionCallConfig.name,\n callInputs: buildFunctionCallConfig.inputs,\n workingDirectory: buildFunctionCallConfig.workingDirectory,\n shell: buildFunctionCallConfig.shell,\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 const buildFunction = this.createBuildFunctionFromConfig({\n id: functionId,\n ...buildFunctionConfig,\n });\n result[buildFunction.getFullId()] = buildFunction;\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 & { id: string }): BuildFunction {\n const inputProviders =\n inputsConfig && this.createBuildStepInputProvidersFromBuildFunctionInputs(inputsConfig);\n const outputProviders =\n outputsConfig && this.createBuildStepOutputProvidersFromBuildFunctionOutputs(outputsConfig);\n return new BuildFunction({ id, name, inputProviders, outputProviders, shell, command });\n }\n\n private createBuildStepInputsFromDefinition(\n buildStepInputs: BuildStepInputs,\n stepDisplayName: string\n ): BuildStepInput[] {\n return Object.entries(buildStepInputs).map(\n ([key, value]) =>\n new BuildStepInput(this.ctx, {\n id: key,\n stepDisplayName,\n defaultValue: value,\n required: true,\n })\n );\n }\n\n private createBuildStepInputProvidersFromBuildFunctionInputs(\n buildFunctionInputs: BuildFunctionInputs\n ): BuildStepInputProvider[] {\n return buildFunctionInputs.map((entry) => {\n return typeof entry === 'string'\n ? BuildStepInput.createProvider({ id: entry })\n : BuildStepInput.createProvider({ id: entry.name, required: entry.required ?? true });\n });\n }\n\n private createBuildStepOutputsFromDefinition(\n buildStepOutputs: BuildStepOutputs,\n stepDisplayName: string\n ): BuildStepOutput[] {\n return buildStepOutputs.map((entry) =>\n typeof entry === 'string'\n ? new BuildStepOutput(this.ctx, { id: entry, stepDisplayName, required: true })\n : new BuildStepOutput(this.ctx, {\n id: entry.name,\n stepDisplayName,\n required: entry.required ?? true,\n })\n );\n }\n\n private createBuildStepOutputProvidersFromBuildFunctionOutputs(\n buildFunctionOutputs: BuildFunctionOutputs\n ): BuildStepOutputProvider[] {\n return buildFunctionOutputs.map((entry) =>\n typeof entry === 'string'\n ? BuildStepOutput.createProvider({ id: entry, required: true })\n : BuildStepOutput.createProvider({ id: entry.name, required: entry.required ?? true })\n );\n }\n\n private mergeBuildFunctionsWithExternal(\n configFunctions: BuildFunctionById,\n externalFunctions?: BuildFunction[]\n ): BuildFunctionById {\n const result: BuildFunctionById = { ...configFunctions };\n if (externalFunctions === undefined) {\n return result;\n }\n for (const buildFunction of externalFunctions) {\n // functions defined in config shadow the external ones\n const fullId = buildFunction.getFullId();\n if (!(fullId in result)) {\n result[fullId] = buildFunction;\n }\n }\n return result;\n }\n\n private validateExternalFunctions(externalFunctions?: BuildFunction[]): void {\n if (externalFunctions === undefined) {\n return;\n }\n const externalFunctionIds = externalFunctions.map((f) => f.getFullId());\n const duplicatedExternalFunctionIds = duplicates(externalFunctionIds);\n if (duplicatedExternalFunctionIds.length === 0) {\n return;\n }\n throw new BuildStepRuntimeError(\n `Provided external functions with duplicated IDs: ${duplicatedExternalFunctionIds\n .map((id) => `\"${id}\"`)\n .join(', ')}`\n );\n }\n\n private getUniqueExternalFunctionIds(): string[] {\n if (this.externalFunctions === undefined) {\n return [];\n }\n const ids = this.externalFunctions.map((f) => f.getFullId());\n return uniq(ids);\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';\n\nimport {\n BuildConfig,\n BuildFunctionConfig,\n BuildFunctionInputs,\n BuildFunctionOutputs,\n BuildStepBareCommandRun,\n BuildStepBareFunctionCall,\n BuildStepCommandRun,\n BuildStepConfig,\n BuildStepFunctionCall,\n BuildStepInputs,\n BuildStepOutputs,\n isBuildStepBareCommandRun,\n isBuildStepBareFunctionCall,\n isBuildStepCommandRun,\n readAndValidateBuildConfigAsync,\n} from './BuildConfig.js';\nimport { BuildFunction, BuildFunctionById } from './BuildFunction.js';\nimport { BuildStep } from './BuildStep.js';\nimport { BuildStepContext } from './BuildStepContext.js';\nimport { BuildStepInput, BuildStepInputProvider } from './BuildStepInput.js';\nimport { BuildStepOutput, BuildStepOutputProvider } from './BuildStepOutput.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildWorkflowValidator } from './BuildWorkflowValidator.js';\nimport { BuildStepRuntimeError } from './errors.js';\nimport { duplicates } from './utils/expodash/duplicates.js';\nimport { uniq } from './utils/expodash/uniq.js';\n\nexport class BuildConfigParser {\n private readonly configPath: string;\n private readonly externalFunctions?: BuildFunction[];\n\n constructor(\n private readonly ctx: BuildStepContext,\n { configPath, externalFunctions }: { configPath: string; externalFunctions?: BuildFunction[] }\n ) {\n this.validateExternalFunctions(externalFunctions);\n\n this.configPath = configPath;\n this.externalFunctions = externalFunctions;\n }\n\n public async parseAsync(): Promise<BuildWorkflow> {\n const config = await readAndValidateBuildConfigAsync(this.configPath, {\n externalFunctionIds: this.getExternalFunctionFullIds(),\n });\n const configBuildFunctions = this.createBuildFunctionsFromConfig(config.functions);\n const buildFunctions = this.mergeBuildFunctionsWithExternal(\n configBuildFunctions,\n this.externalFunctions\n );\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 createBuildStepFromConfig(\n buildStepConfig: BuildStepConfig,\n buildFunctions: BuildFunctionById\n ): BuildStep {\n if (isBuildStepCommandRun(buildStepConfig)) {\n return this.createBuildStepFromBuildStepCommandRun(buildStepConfig);\n } else if (isBuildStepBareCommandRun(buildStepConfig)) {\n return this.createBuildStepFromBuildStepBareCommandRun(buildStepConfig);\n } else if (isBuildStepBareFunctionCall(buildStepConfig)) {\n return this.createBuildStepFromBuildStepBareFunctionCall(buildFunctions, buildStepConfig);\n } else {\n return this.createBuildStepFromBuildStepFunctionCall(buildFunctions, buildStepConfig);\n }\n }\n\n private createBuildStepFromBuildStepCommandRun({ run }: BuildStepCommandRun): BuildStep {\n const {\n id: maybeId,\n inputs: inputsConfig,\n outputs: outputsConfig,\n name,\n workingDirectory,\n shell,\n command,\n } = run;\n const id = BuildStep.getNewId(maybeId);\n const displayName = BuildStep.getDisplayName({ id, name, command });\n const inputs =\n inputsConfig && this.createBuildStepInputsFromDefinition(inputsConfig, displayName);\n const outputs =\n outputsConfig && this.createBuildStepOutputsFromDefinition(outputsConfig, displayName);\n return new BuildStep(this.ctx, {\n id,\n inputs,\n outputs,\n name,\n displayName,\n workingDirectory,\n shell,\n command,\n });\n }\n\n private createBuildStepFromBuildStepBareCommandRun({\n run: command,\n }: BuildStepBareCommandRun): BuildStep {\n const id = BuildStep.getNewId();\n const displayName = BuildStep.getDisplayName({ id, command });\n return new BuildStep(this.ctx, {\n id,\n displayName,\n command,\n });\n }\n\n private createBuildStepFromBuildStepBareFunctionCall(\n buildFunctions: BuildFunctionById,\n functionId: BuildStepBareFunctionCall\n ): BuildStep {\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall(this.ctx);\n }\n\n private createBuildStepFromBuildStepFunctionCall(\n buildFunctions: BuildFunctionById,\n buildStepFunctionCall: BuildStepFunctionCall\n ): BuildStep {\n const keys = Object.keys(buildStepFunctionCall);\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 = buildStepFunctionCall[functionId];\n const buildFunction = buildFunctions[functionId];\n return buildFunction.createBuildStepFromFunctionCall(this.ctx, {\n id: buildFunctionCallConfig.id,\n name: buildFunctionCallConfig.name,\n callInputs: buildFunctionCallConfig.inputs,\n workingDirectory: buildFunctionCallConfig.workingDirectory,\n shell: buildFunctionCallConfig.shell,\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 const buildFunction = this.createBuildFunctionFromConfig({\n id: functionId,\n ...buildFunctionConfig,\n });\n result[buildFunction.getFullId()] = buildFunction;\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 & { id: string }): BuildFunction {\n const inputProviders =\n inputsConfig && this.createBuildStepInputProvidersFromBuildFunctionInputs(inputsConfig);\n const outputProviders =\n outputsConfig && this.createBuildStepOutputProvidersFromBuildFunctionOutputs(outputsConfig);\n return new BuildFunction({ id, name, inputProviders, outputProviders, shell, command });\n }\n\n private createBuildStepInputsFromDefinition(\n buildStepInputs: BuildStepInputs,\n stepDisplayName: string\n ): BuildStepInput[] {\n return Object.entries(buildStepInputs).map(\n ([key, value]) =>\n new BuildStepInput(this.ctx, {\n id: key,\n stepDisplayName,\n defaultValue: value,\n required: true,\n })\n );\n }\n\n private createBuildStepInputProvidersFromBuildFunctionInputs(\n buildFunctionInputs: BuildFunctionInputs\n ): BuildStepInputProvider[] {\n return buildFunctionInputs.map((entry) => {\n return typeof entry === 'string'\n ? BuildStepInput.createProvider({ id: entry })\n : BuildStepInput.createProvider({\n id: entry.name,\n required: entry.required ?? true,\n defaultValue: entry.defaultValue,\n allowedValues: entry.allowedValues,\n });\n });\n }\n\n private createBuildStepOutputsFromDefinition(\n buildStepOutputs: BuildStepOutputs,\n stepDisplayName: string\n ): BuildStepOutput[] {\n return buildStepOutputs.map((entry) =>\n typeof entry === 'string'\n ? new BuildStepOutput(this.ctx, { id: entry, stepDisplayName, required: true })\n : new BuildStepOutput(this.ctx, {\n id: entry.name,\n stepDisplayName,\n required: entry.required ?? true,\n })\n );\n }\n\n private createBuildStepOutputProvidersFromBuildFunctionOutputs(\n buildFunctionOutputs: BuildFunctionOutputs\n ): BuildStepOutputProvider[] {\n return buildFunctionOutputs.map((entry) =>\n typeof entry === 'string'\n ? BuildStepOutput.createProvider({ id: entry, required: true })\n : BuildStepOutput.createProvider({ id: entry.name, required: entry.required ?? true })\n );\n }\n\n private mergeBuildFunctionsWithExternal(\n configFunctions: BuildFunctionById,\n externalFunctions?: BuildFunction[]\n ): BuildFunctionById {\n const result: BuildFunctionById = { ...configFunctions };\n if (externalFunctions === undefined) {\n return result;\n }\n for (const buildFunction of externalFunctions) {\n // functions defined in config shadow the external ones\n const fullId = buildFunction.getFullId();\n if (!(fullId in result)) {\n result[fullId] = buildFunction;\n }\n }\n return result;\n }\n\n private validateExternalFunctions(externalFunctions?: BuildFunction[]): void {\n if (externalFunctions === undefined) {\n return;\n }\n const externalFunctionIds = externalFunctions.map((f) => f.getFullId());\n const duplicatedExternalFunctionIds = duplicates(externalFunctionIds);\n if (duplicatedExternalFunctionIds.length === 0) {\n return;\n }\n throw new BuildStepRuntimeError(\n `Provided external functions with duplicated IDs: ${duplicatedExternalFunctionIds\n .map((id) => `\"${id}\"`)\n .join(', ')}`\n );\n }\n\n private getExternalFunctionFullIds(): string[] {\n if (this.externalFunctions === undefined) {\n return [];\n }\n const ids = this.externalFunctions.map((f) => f.getFullId());\n return uniq(ids);\n }\n}\n"]}
@@ -15,6 +15,7 @@ export declare class BuildFunction {
15
15
  readonly command?: string;
16
16
  readonly fn?: BuildStepFunction;
17
17
  readonly shell?: string;
18
+ static isFulldIdNamespaced(fullId: string): boolean;
18
19
  constructor({ namespace, id, name, platforms, inputProviders, outputProviders, command, fn, shell, }: {
19
20
  namespace?: string;
20
21
  id: string;
@@ -1,6 +1,9 @@
1
1
  import assert from 'assert';
2
2
  import { BuildStep } from './BuildStep.js';
3
3
  export class BuildFunction {
4
+ static isFulldIdNamespaced(fullId) {
5
+ return fullId.includes('/');
6
+ }
4
7
  constructor({ namespace, id, name, platforms, inputProviders, outputProviders, command, fn, shell, }) {
5
8
  assert(command !== undefined || fn !== undefined, 'Either command or fn must be defined.');
6
9
  assert(!(command !== undefined && fn !== undefined), 'Command and fn cannot be both set.');