From 8631b40d542f7a7b3acded2dd22fec4a99649129 Mon Sep 17 00:00:00 2001 From: Michal Jez Date: Tue, 30 Apr 2024 13:53:19 -0400 Subject: [PATCH] feat(core): validate that outputs is an array of strings (#22371) --- packages/nx/src/tasks-runner/utils.spec.ts | 20 +++++++++++++++++ packages/nx/src/tasks-runner/utils.ts | 25 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/packages/nx/src/tasks-runner/utils.spec.ts b/packages/nx/src/tasks-runner/utils.spec.ts index 438cbf0f36530..8cbc72b2cbdb4 100644 --- a/packages/nx/src/tasks-runner/utils.spec.ts +++ b/packages/nx/src/tasks-runner/utils.spec.ts @@ -489,4 +489,24 @@ describe('utils', () => { }); }); }); + + describe('validateOutputs', () => { + it('returns undefined if there are no errors', () => { + expect(validateOutputs(['{projectRoot}/dist'])).toBeUndefined(); + }); + + it('throws an error if the output is not an array', () => { + expect(() => validateOutputs('output' as unknown as string[])).toThrow( + "The 'outputs' field must be an array" + ); + }); + + it("throws an error if the output has entries that aren't strings", () => { + expect(() => + validateOutputs(['foo', 1, null, true, {}, []] as unknown as string[]) + ).toThrow( + "The 'outputs' field must contain only strings, but received types: [string, number, object, boolean, object, object]" + ); + }); + }); }); diff --git a/packages/nx/src/tasks-runner/utils.ts b/packages/nx/src/tasks-runner/utils.ts index 9038fd30379dc..ad3a0b802b9f5 100644 --- a/packages/nx/src/tasks-runner/utils.ts +++ b/packages/nx/src/tasks-runner/utils.ts @@ -107,7 +107,32 @@ class InvalidOutputsError extends Error { } } +function assertOutputsAreValidType(outputs: unknown) { + if (!Array.isArray(outputs)) { + throw new Error("The 'outputs' field must be an array"); + } + + const typesArray = []; + let hasInvalidType = false; + for (const output of outputs) { + if (typeof output !== 'string') { + hasInvalidType = true; + } + typesArray.push(typeof output); + } + + if (hasInvalidType) { + throw new Error( + `The 'outputs' field must contain only strings, but received types: [${typesArray.join( + ', ' + )}]` + ); + } +} + export function validateOutputs(outputs: string[]) { + assertOutputsAreValidType(outputs); + const invalidOutputs = new Set(); for (const output of outputs) {