From 5451ca51a8148dc897a6c578e9c5e51b92358130 Mon Sep 17 00:00:00 2001 From: Jack Kleeman Date: Mon, 14 Oct 2024 10:46:53 +0100 Subject: [PATCH] Require triple equals via eslint (#447) --- .eslintrc.json | 1 + .../src/non_determinism.ts | 2 +- packages/restate-e2e-services/src/workflow.ts | 2 +- packages/restate-sdk-clients/src/ingress.ts | 8 +++--- packages/restate-sdk-core/src/serde_api.ts | 4 +-- packages/restate-sdk/src/context.ts | 8 +++--- packages/restate-sdk/src/context_impl.ts | 26 +++++++++---------- .../src/endpoint/handlers/generic.ts | 9 ++++--- packages/restate-sdk/src/logger.ts | 2 +- packages/restate-sdk/src/types/components.ts | 4 +-- packages/restate-sdk/src/types/errors.ts | 2 +- packages/restate-sdk/src/types/rpc.ts | 18 ++++++------- packages/restate-sdk/src/utils/rand.ts | 2 +- 13 files changed, 46 insertions(+), 42 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 60c6d9a1..11ed6ea0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -34,6 +34,7 @@ "plugins": ["@typescript-eslint", "require-extensions"], "rules": { "no-console": "error", + "eqeqeq": "error", "@typescript-eslint/consistent-type-imports": "error", "@typescript-eslint/consistent-type-exports": "error", "@typescript-eslint/restrict-template-expressions": [ diff --git a/packages/restate-e2e-services/src/non_determinism.ts b/packages/restate-e2e-services/src/non_determinism.ts index 2afd8945..a011e584 100644 --- a/packages/restate-e2e-services/src/non_determinism.ts +++ b/packages/restate-e2e-services/src/non_determinism.ts @@ -21,7 +21,7 @@ const invocationCounts = new Map(); function doLeftAction(ctx: restate.ObjectContext): boolean { const newValue = (invocationCounts.get(ctx.key) ?? 0) + 1; invocationCounts.set(ctx.key, newValue); - return newValue % 2 == 1; + return newValue % 2 === 1; } function incrementCounter(ctx: restate.ObjectContext) { diff --git a/packages/restate-e2e-services/src/workflow.ts b/packages/restate-e2e-services/src/workflow.ts index 6167ccc9..623d0bc4 100644 --- a/packages/restate-e2e-services/src/workflow.ts +++ b/packages/restate-e2e-services/src/workflow.ts @@ -18,7 +18,7 @@ const wf = restate.workflow({ const output = await ctx.promise("p"); - if (ctx.promise("p").peek() == undefined) { + if (ctx.promise("p").peek() === undefined) { throw new restate.TerminalError("Durable promise should be completed"); } diff --git a/packages/restate-sdk-clients/src/ingress.ts b/packages/restate-sdk-clients/src/ingress.ts index 009acd3e..53f681b1 100644 --- a/packages/restate-sdk-clients/src/ingress.ts +++ b/packages/restate-sdk-clients/src/ingress.ts @@ -318,7 +318,7 @@ class HttpIngress implements Ingress { result, }; } catch (e) { - if (!(e instanceof HttpCallError) || e.status != 470) { + if (!(e instanceof HttpCallError) || e.status !== 470) { throw e; } return { @@ -335,11 +335,11 @@ class HttpIngress implements Ingress { { get: (_target, prop) => { const handler = prop as string; - if (handler == "workflowSubmit") { + if (handler === "workflowSubmit") { return workflowSubmit; - } else if (handler == "workflowAttach") { + } else if (handler === "workflowAttach") { return workflowAttach; - } else if (handler == "workflowOutput") { + } else if (handler === "workflowOutput") { return workflowOutput; } // shared handlers pass trough via the ingress's normal invocation form diff --git a/packages/restate-sdk-core/src/serde_api.ts b/packages/restate-sdk-core/src/serde_api.ts index 032a78a7..9dc7f229 100644 --- a/packages/restate-sdk-core/src/serde_api.ts +++ b/packages/restate-sdk-core/src/serde_api.ts @@ -32,7 +32,7 @@ class JsonSerde implements Serde { } deserialize(data: Uint8Array): T | undefined { - if (data.length == 0) { + if (data.length === 0) { return undefined; } return JSON.parse(new TextDecoder().decode(data)) as T; @@ -62,7 +62,7 @@ class VoidSerde implements Serde { } deserialize(data: Uint8Array): void { - if (data.length != 0) { + if (data.length !== 0) { throw new Error("Expected empty data"); } } diff --git a/packages/restate-sdk/src/context.ts b/packages/restate-sdk/src/context.ts index 48ff6b00..e04c607b 100644 --- a/packages/restate-sdk/src/context.ts +++ b/packages/restate-sdk/src/context.ts @@ -606,7 +606,7 @@ export const CombineablePromise = { all[] | []>( values: T ): Promise<{ -readonly [P in keyof T]: Awaited }> { - if (values.length == 0) { + if (values.length === 0) { return Promise.all(values); } return ContextImpl.createCombinator("All", values) as Promise<{ @@ -626,7 +626,7 @@ export const CombineablePromise = { race[] | []>( values: T ): Promise> { - if (values.length == 0) { + if (values.length === 0) { return Promise.race(values); } return ContextImpl.createCombinator("Race", values) as Promise< @@ -647,7 +647,7 @@ export const CombineablePromise = { any[] | []>( values: T ): Promise> { - if (values.length == 0) { + if (values.length === 0) { return Promise.any(values); } return ContextImpl.createCombinator("Any", values) as Promise< @@ -669,7 +669,7 @@ export const CombineablePromise = { ): Promise<{ -readonly [P in keyof T]: PromiseSettledResult>; }> { - if (values.length == 0) { + if (values.length === 0) { return Promise.allSettled(values); } return ContextImpl.createCombinator("AllSettled", values) as Promise<{ diff --git a/packages/restate-sdk/src/context_impl.ts b/packages/restate-sdk/src/context_impl.ts index 9cb92093..555d7c57 100644 --- a/packages/restate-sdk/src/context_impl.ts +++ b/packages/restate-sdk/src/context_impl.ts @@ -99,7 +99,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { }, new Map()), attemptHeaders: Object.entries(attemptHeaders).reduce( (headers, [key, value]) => { - if (value != undefined) { + if (value !== undefined) { headers.set(key, value instanceof Array ? value[0] : value); } return headers; @@ -139,7 +139,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { return this.processCompletableEntry( (vm) => vm.sys_get_state(name), (asyncResultValue) => { - if (asyncResultValue == "Empty") { + if (asyncResultValue === "Empty") { // Empty return null; } else if ("Success" in asyncResultValue) { @@ -244,7 +244,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { const parameter = requestSerde.serialize(send.parameter); let delay; - if (send.delay != undefined) { + if (send.delay !== undefined) { delay = BigInt(send.delay); } @@ -358,7 +358,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { // Record the result/failure, get back the handle for the ack. let handle; try { - if (err != undefined) { + if (err !== undefined) { if (err instanceof TerminalError) { // Record failure, go ahead handle = this.coreVm.sys_run_exit_failure({ @@ -409,7 +409,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { return this.processCompletableEntry( (vm) => vm.sys_sleep(BigInt(millis)), (asyncResultValue) => { - if (asyncResultValue == "Empty") { + if (asyncResultValue === "Empty") { // Empty return undefined as void; } else if ("Failure" in asyncResultValue) { @@ -453,7 +453,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { if (!serde) { return defaultSerde().deserialize(asyncResultValue.Success); } - if (asyncResultValue.Success.length == 0) { + if (asyncResultValue.Success.length === 0) { return undefined as T; } return serde.deserialize(asyncResultValue.Success); @@ -482,10 +482,10 @@ export class ContextImpl implements ObjectContext, WorkflowContext { if (serde) { value = - payload == undefined ? new Uint8Array() : serde.serialize(payload); + payload === undefined ? new Uint8Array() : serde.serialize(payload); } else { value = - payload != undefined + payload !== undefined ? defaultSerde().serialize(payload) : defaultSerde().serialize(null); } @@ -634,7 +634,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { return promisesMap.get(handlesResult[0]); case "OrTimeout": // The sleep promise is always the second one in the list. - if (handlesResult[0] == castedPromises[1].asyncResultHandle) { + if (handlesResult[0] === castedPromises[1].asyncResultHandle) { return Promise.reject(new TimeoutError()); } else { return promisesMap.get(handlesResult[0]); @@ -751,7 +751,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { // Now loop waiting for the async result let asyncResult = this.coreVm.take_async_result(handle); - while (asyncResult == "NotReady") { + while (asyncResult === "NotReady") { await this.awaitNextRead(); // Using notify_await_point immediately before take_async_result // makes sure the state machine will try to suspend only now, @@ -776,7 +776,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { // and will notify the caller that a read was executed // and the result was piped in the state machine. private awaitNextRead(): Promise { - if (this.currentRead == undefined) { + if (this.currentRead === undefined) { // Register a new read this.currentRead = this.readNext().finally(() => { this.currentRead = undefined; @@ -808,7 +808,7 @@ export class ContextImpl implements ObjectContext, WorkflowContext { const error = ensureError(e); if ( !(error instanceof RestateError) || - error.code != SUSPENDED_ERROR_CODE + error.code !== SUSPENDED_ERROR_CODE ) { this.console.warn("Function completed with an error.\n", error); } @@ -823,7 +823,7 @@ function unpack( a: string | RunAction, b?: RunAction ): { name?: string; action: RunAction } { - if (typeof a == "string") { + if (typeof a === "string") { if (typeof b !== "function") { throw new TypeError(""); } diff --git a/packages/restate-sdk/src/endpoint/handlers/generic.ts b/packages/restate-sdk/src/endpoint/handlers/generic.ts index 473b7c4b..8693f82a 100644 --- a/packages/restate-sdk/src/endpoint/handlers/generic.ts +++ b/packages/restate-sdk/src/endpoint/handlers/generic.ts @@ -97,7 +97,10 @@ export class GenericHandler implements RestateHandler { private readonly protocolMode: ProtocolMode ) { // Setup identity verifier - if (this.endpoint.keySet == undefined || this.endpoint.keySet.length == 0) { + if ( + this.endpoint.keySet === undefined || + this.endpoint.keySet.length === 0 + ) { this.endpoint.rlog.warn( `Accepting requests without validating request signatures; handler access must be restricted` ); @@ -257,7 +260,7 @@ export class GenericHandler implements RestateHandler { // Now buffer input entries while (!coreVm.is_ready_to_execute()) { const nextValue = await inputReader.read(); - if (nextValue.value != undefined) { + if (nextValue.value !== undefined) { coreVm.notify_input(nextValue.value); } if (nextValue.done) { @@ -318,7 +321,7 @@ export class GenericHandler implements RestateHandler { const error = ensureError(e); if ( !(error instanceof RestateError) || - error.code != SUSPENDED_ERROR_CODE + error.code !== SUSPENDED_ERROR_CODE ) { console.warn("Function completed with an error.\n", error); } diff --git a/packages/restate-sdk/src/logger.ts b/packages/restate-sdk/src/logger.ts index 7f054be0..e7c298c5 100644 --- a/packages/restate-sdk/src/logger.ts +++ b/packages/restate-sdk/src/logger.ts @@ -108,7 +108,7 @@ export const defaultLogger: Logger = ( function readRestateLogLevel(): RestateLogLevel { const env = globalThis.process?.env?.RESTATE_LOGGING; const level = logLevelFromName(env); - if (level != null) { + if (level !== null) { return level; } return RestateLogLevel.INFO; diff --git a/packages/restate-sdk/src/types/components.ts b/packages/restate-sdk/src/types/components.ts index 7ec70208..bcbb2a0d 100644 --- a/packages/restate-sdk/src/types/components.ts +++ b/packages/restate-sdk/src/types/components.ts @@ -145,7 +145,7 @@ export class VirtualObjectComponent implements Component { contentType: opts.contentType ?? "application/json", }, ty: - opts.kind == HandlerKind.EXCLUSIVE + opts.kind === HandlerKind.EXCLUSIVE ? d.ServiceHandlerType.EXCLUSIVE : d.ServiceHandlerType.SHARED, }; @@ -220,7 +220,7 @@ export class WorkflowComponent implements Component { contentType: handler.contentType ?? "application/json", }, ty: - handler.kind == HandlerKind.WORKFLOW + handler.kind === HandlerKind.WORKFLOW ? d.ServiceHandlerType.WORKFLOW : d.ServiceHandlerType.SHARED, }; diff --git a/packages/restate-sdk/src/types/errors.ts b/packages/restate-sdk/src/types/errors.ts index 22ed61ed..e702d091 100644 --- a/packages/restate-sdk/src/types/errors.ts +++ b/packages/restate-sdk/src/types/errors.ts @@ -22,7 +22,7 @@ export function ensureError(e: unknown): Error { if (e instanceof Error) { return e; } - if (typeof e == "object" && e != null && "code" in e && "message" in e) { + if (typeof e === "object" && e !== null && "code" in e && "message" in e) { // This is an error from the VM return new RestateError(e.message as string, { errorCode: e.code as number, diff --git a/packages/restate-sdk/src/types/rpc.ts b/packages/restate-sdk/src/types/rpc.ts index c075a91a..1c94bd34 100644 --- a/packages/restate-sdk/src/types/rpc.ts +++ b/packages/restate-sdk/src/types/rpc.ts @@ -409,7 +409,7 @@ export class HandlerWrapper { } else if (opts?.accept) { // accept but no serializer, use pass trough inputSerde = new DeserializerWrapper(opts.accept, (input) => input); - } else if (opts?.contentType == JSON_CONTENT_TYPE) { + } else if (opts?.contentType === JSON_CONTENT_TYPE) { // contentType is JSON, use the default serde inputSerde = defaultSerde(); } else if (opts?.input) { @@ -426,7 +426,7 @@ export class HandlerWrapper { opts.contentType ?? JSON_CONTENT_TYPE, opts.outputSerializer ); - } else if (opts?.contentType == JSON_CONTENT_TYPE) { + } else if (opts?.contentType === JSON_CONTENT_TYPE) { // contentType is JSON, use the default serde outputSerde = defaultSerde(); } else if (opts?.contentType) { @@ -541,7 +541,7 @@ export namespace handlers { optsOrFn: WorkflowHandlerOpts | WorkflowHandler>, fn?: WorkflowHandler> ): F { - if (typeof optsOrFn == "function") { + if (typeof optsOrFn === "function") { return HandlerWrapper.from(HandlerKind.WORKFLOW, optsOrFn).transpose(); } const opts = optsOrFn satisfies WorkflowHandlerOpts; @@ -593,7 +593,7 @@ export namespace handlers { | WorkflowSharedHandler>, fn?: WorkflowSharedHandler> ): F { - if (typeof optsOrFn == "function") { + if (typeof optsOrFn === "function") { return HandlerWrapper.from(HandlerKind.SHARED, optsOrFn).transpose(); } const opts = optsOrFn satisfies ObjectHandlerOpts; @@ -649,7 +649,7 @@ export namespace handlers { optsOrFn: ObjectHandlerOpts | ObjectHandler>, fn?: ObjectHandler> ): F { - if (typeof optsOrFn == "function") { + if (typeof optsOrFn === "function") { return HandlerWrapper.from(HandlerKind.EXCLUSIVE, optsOrFn).transpose(); } const opts = optsOrFn satisfies ObjectHandlerOpts; @@ -707,7 +707,7 @@ export namespace handlers { | ObjectSharedHandler>, fn?: ObjectSharedHandler> ): F { - if (typeof optsOrFn == "function") { + if (typeof optsOrFn === "function") { return HandlerWrapper.from(HandlerKind.SHARED, optsOrFn).transpose(); } const opts = optsOrFn satisfies ObjectHandlerOpts; @@ -973,7 +973,7 @@ export const workflow =

(workflow: { } else { throw new TypeError(`Missing main workflow handler, named 'run'`); } - if (runWrapper.kind != HandlerKind.WORKFLOW) { + if (runWrapper.kind !== HandlerKind.WORKFLOW) { throw new TypeError( `Workflow's main handler handler run, must be of type workflow'` ); @@ -986,7 +986,7 @@ export const workflow =

(workflow: { // for (const [name, handler] of Object.entries(workflow.handlers)) { - if (name == "run") { + if (name === "run") { continue; } let wrapper: HandlerWrapper; @@ -1000,7 +1000,7 @@ export const workflow =

(workflow: { } else { throw new TypeError(`Unexpected handler type ${name}`); } - if (wrapper.kind == HandlerKind.WORKFLOW) { + if (wrapper.kind === HandlerKind.WORKFLOW) { throw new TypeError( `A workflow must contain exactly one handler annotated as workflow, named 'run'. Please use a shared handler for any additional handlers` ); diff --git a/packages/restate-sdk/src/utils/rand.ts b/packages/restate-sdk/src/utils/rand.ts index 78715cca..9fb1025c 100644 --- a/packages/restate-sdk/src/utils/rand.ts +++ b/packages/restate-sdk/src/utils/rand.ts @@ -24,7 +24,7 @@ export class RandImpl implements Rand { id: string | [bigint, bigint, bigint, bigint], private readonly checkState: (state: string) => void = () => undefined ) { - if (typeof id == "string") { + if (typeof id === "string") { // hash the invocation ID, which is known to contain 74 bits of entropy const hash = createHash("sha256").update(id).digest();