From 4a0b46314ab4f250a22b2592b896e3a95bccf18c Mon Sep 17 00:00:00 2001 From: Dominic Griesel Date: Tue, 29 Oct 2024 12:33:12 +0100 Subject: [PATCH] fix: validateArgs transformer --- packages/flash/src/cli.ts | 4 +-- .../transformers/src/validateArgs/reason.ts | 5 +++ .../src/validateArgs/visitor-type-check.ts | 34 ++++++++++++++++++ .../src/validateArgs/visitor-type-name.ts | 2 ++ .../src/validateArgs/visitor-utils.ts | 12 +++++++ .../test/fixtures/testUint8Array.ts | 35 +++++++++++++++++++ 6 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 packages/transformers/test/fixtures/testUint8Array.ts diff --git a/packages/flash/src/cli.ts b/packages/flash/src/cli.ts index 83b81a21f174..51caecbd7e7a 100644 --- a/packages/flash/src/cli.ts +++ b/packages/flash/src/cli.ts @@ -21,7 +21,7 @@ if (!port || !filename) { const verbose = !!argv.verbose; -let firmware: Buffer; +let firmware: Uint8Array; const driver = new Driver(port, { logConfig: verbose @@ -99,7 +99,7 @@ async function flash() { } async function main() { - let rawFile: Buffer; + let rawFile: Uint8Array; try { const fullPath = path.isAbsolute(filename) ? filename diff --git a/packages/transformers/src/validateArgs/reason.ts b/packages/transformers/src/validateArgs/reason.ts index 4a5f419a929d..de60aa8cf7a9 100644 --- a/packages/transformers/src/validateArgs/reason.ts +++ b/packages/transformers/src/validateArgs/reason.ts @@ -45,6 +45,10 @@ export interface ExpectedBuffer { type: "buffer"; } +export interface ExpectedUint8Array { + type: "uint8array"; +} + export interface ExpectedClass { type: "class"; name: string; @@ -118,6 +122,7 @@ export type Reason = | ExpectedObject | ExpectedDate | ExpectedBuffer + | ExpectedUint8Array | ExpectedClass | ExpectedNonPrimitive | MissingObjectProperty diff --git a/packages/transformers/src/validateArgs/visitor-type-check.ts b/packages/transformers/src/validateArgs/visitor-type-check.ts index 4985be70a896..fd9359e4e2af 100644 --- a/packages/transformers/src/validateArgs/visitor-type-check.ts +++ b/packages/transformers/src/validateArgs/visitor-type-check.ts @@ -114,6 +114,38 @@ function visitBufferType(type: ts.ObjectType, visitorContext: VisitorContext) { }); } +function visitUint8ArrayType( + type: ts.ObjectType, + visitorContext: VisitorContext, +) { + const name = VisitorTypeName.visitType(type, visitorContext, { + type: "type-check", + }); + const f = visitorContext.factory; + return VisitorUtils.setFunctionIfNotExists(name, visitorContext, () => { + return VisitorUtils.createAssertionFunction( + f.createPrefixUnaryExpression( + ts.SyntaxKind.ExclamationToken, + f.createCallExpression( + f.createPropertyAccessExpression( + f.createCallExpression( + f.createIdentifier("require"), + undefined, + [f.createStringLiteral("@zwave-js/shared/safe")], + ), + f.createIdentifier("isUint8Array"), + ), + undefined, + [VisitorUtils.objectIdentifier], + ), + ), + { type: "uint8array" }, + name, + visitorContext, + ); + }); +} + function visitClassType(type: ts.ObjectType, visitorContext: VisitorContext) { const f = visitorContext.factory; const name = VisitorTypeName.visitType(type, visitorContext, { @@ -687,6 +719,8 @@ function visitObjectType(type: ts.ObjectType, visitorContext: VisitorContext) { return visitDateType(type, visitorContext); } else if (VisitorUtils.checkIsNodeBuffer(type)) { return visitBufferType(type, visitorContext); + } else if (VisitorUtils.checkIsUint8Array(type)) { + return visitUint8ArrayType(type, visitorContext); } else if (VisitorUtils.checkIsIgnoredIntrinsic(type)) { // This is an intrinsic type we can't check properly, so we just ignore it. return VisitorUtils.getIgnoredTypeFunction(visitorContext); diff --git a/packages/transformers/src/validateArgs/visitor-type-name.ts b/packages/transformers/src/validateArgs/visitor-type-name.ts index e21a26fc0bd6..251e611d3814 100644 --- a/packages/transformers/src/validateArgs/visitor-type-name.ts +++ b/packages/transformers/src/validateArgs/visitor-type-name.ts @@ -110,6 +110,8 @@ function visitObjectType( return visitTupleObjectType(type, visitorContext, mode); } else if (checkIsNodeBuffer(type)) { return "_buffer"; + } else if (VisitorUtils.checkIsUint8Array(type)) { + return "_uint8array"; } else if ( visitorContext.checker.getIndexTypeOfType(type, ts.IndexKind.Number) ) { diff --git a/packages/transformers/src/validateArgs/visitor-utils.ts b/packages/transformers/src/validateArgs/visitor-utils.ts index 5fc1e65ef75e..8247d2a149ee 100644 --- a/packages/transformers/src/validateArgs/visitor-utils.ts +++ b/packages/transformers/src/validateArgs/visitor-utils.ts @@ -84,6 +84,18 @@ export function checkIsNodeBuffer(type: ts.ObjectType): boolean { ); } +export function checkIsUint8Array(type: ts.ObjectType): boolean { + return ( + type.symbol !== undefined + && type.symbol.valueDeclaration !== undefined + && type.symbol.name === "Uint8Array" + && !!( + ts.getCombinedModifierFlags(type.symbol.valueDeclaration) + & ts.ModifierFlags.Ambient + ) + ); +} + export function checkIsIgnoredIntrinsic(type: ts.ObjectType): boolean { return ( type.symbol !== undefined diff --git a/packages/transformers/test/fixtures/testUint8Array.ts b/packages/transformers/test/fixtures/testUint8Array.ts new file mode 100644 index 000000000000..337ba7794640 --- /dev/null +++ b/packages/transformers/test/fixtures/testUint8Array.ts @@ -0,0 +1,35 @@ +/* eslint-disable no-restricted-globals */ +import { validateArgs } from "@zwave-js/transformers"; +import assert from "node:assert"; + +class Test { + @validateArgs() + foo(arg1: Uint8Array): void { + arg1; + return void 0; + } +} + +const test = new Test(); +// These should not throw +test.foo(new Uint8Array()); +test.foo(Uint8Array.from([0xaa, 0xbb, 0xcc])); +// These should also not throw +test.foo(Buffer.alloc(0)); + +// These should throw +assert.throws( + // @ts-expect-error + () => test.foo("string"), + /arg1 is not a Uint8Array/, +); +assert.throws( + // @ts-expect-error + () => test.foo(undefined), + /arg1 is not a Uint8Array/, +); +assert.throws( + // @ts-expect-error + () => test.foo({ type: "Buffer", data: [170, 187, 204] }), + /arg1 is not a Uint8Array/, +);