From 1aa139e87cfbefb211bcadc2c68fb521a7fc1c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Thu, 11 Jul 2024 20:35:21 +0200 Subject: [PATCH] Make operations work with any (#2170) --- .../sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/server/operations/wrappers.ts | 25 ++++++++++++-- .../templates/sdk/wasp/universal/types.ts | 6 +++- .../waspBuild/.wasp/build/.waspchecksums | 6 ++-- .../build/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 7 ++-- .../build/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 14 ++++++-- .../.wasp/build/sdk/wasp/universal/types.ts | 6 +++- .../out/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 7 ++-- .../out/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 14 ++++++-- .../.wasp/out/sdk/wasp/universal/types.ts | 6 +++- .../waspCompile/.wasp/out/.waspchecksums | 6 ++-- .../out/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 7 ++-- .../out/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 14 ++++++-- .../.wasp/out/sdk/wasp/universal/types.ts | 6 +++- .../waspComplexTest/.wasp/out/.waspchecksums | 6 ++-- .../out/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../dist/client/crud/operationsHelpers.d.ts | 2 +- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 12 ++++--- .../out/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 25 ++++++++++++-- .../.wasp/out/sdk/wasp/universal/types.ts | 6 +++- .../waspJob/.wasp/out/.waspchecksums | 6 ++-- .../out/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 7 ++-- .../out/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 14 ++++++-- .../.wasp/out/sdk/wasp/universal/types.ts | 6 +++- .../waspMigrate/.wasp/out/.waspchecksums | 6 ++-- .../out/sdk/wasp/client/operations/rpc.ts | 26 +++++++++++---- .../sdk/wasp/dist/client/operations/rpc.d.ts | 7 ++-- .../wasp/dist/server/operations/wrappers.d.ts | 7 ++-- .../out/sdk/wasp/dist/universal/types.d.ts | 1 + .../sdk/wasp/server/operations/wrappers.ts | 14 ++++++-- .../.wasp/out/sdk/wasp/universal/types.ts | 6 +++- waspc/examples/todoApp/main.wasp | 32 ++++++++++++++++-- waspc/examples/todoApp/src/Todo.tsx | 4 +-- .../src/testTypes/operations/client.ts | 19 +++++++++-- .../src/testTypes/operations/definitions.ts | 25 ++++++++++++-- .../src/testTypes/operations/server.ts | 33 ++++++++++++++++--- 50 files changed, 452 insertions(+), 132 deletions(-) diff --git a/waspc/data/Generator/templates/sdk/wasp/client/operations/rpc.ts b/waspc/data/Generator/templates/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/data/Generator/templates/sdk/wasp/client/operations/rpc.ts +++ b/waspc/data/Generator/templates/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/data/Generator/templates/sdk/wasp/server/operations/wrappers.ts b/waspc/data/Generator/templates/sdk/wasp/server/operations/wrappers.ts index 3f8e795a3..15b7060cd 100644 --- a/waspc/data/Generator/templates/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/data/Generator/templates/sdk/wasp/server/operations/wrappers.ts @@ -1,5 +1,5 @@ {{={= =}=}} -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' {=# isAuthEnabled =} import { type AuthUser } from 'wasp/auth' @@ -160,6 +160,9 @@ function includesPayload( type AuthenticatedOperationArgsFor = Parameters> +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before attempting to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 /** * Constructs the type for an authenticated operation's server-side API. * @@ -168,6 +171,14 @@ type AuthenticatedOperationArgsFor = + IfAny< + Input, + (args: any, context: { user: AuthUser }) => Promise, + AuthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type AuthenticatedOperationWithNonAnyInput = [Input] extends [never] ? (args: unknown, context: { user: AuthUser }) => Promise : [Input] extends [void] @@ -187,6 +198,7 @@ type GenericAuthenticatedOperationDefinition = AuthenticatedOperationDefinition< > {=/ isAuthEnabled =} +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -195,13 +207,20 @@ type GenericAuthenticatedOperationDefinition = AuthenticatedOperationDefinition< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/data/Generator/templates/sdk/wasp/universal/types.ts b/waspc/data/Generator/templates/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/data/Generator/templates/sdk/wasp/universal/types.ts +++ b/waspc/data/Generator/templates/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/.waspchecksums b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/.waspchecksums index f04248225..c2f4e82cb 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/.waspchecksums @@ -102,7 +102,7 @@ "file", "../out/sdk/wasp/client/operations/rpc.ts" ], - "63fb0670b2ccff4ad005bbb76597572a60e01f31b739d7bc764bb59c4f3c53d4" + "08f30fe4e31a691a225949ccd4d638cffe78bf2f4f2a76feb70133d4d9a5ba94" ], [ [ @@ -305,7 +305,7 @@ "file", "../out/sdk/wasp/server/operations/wrappers.ts" ], - "4f3ffd00d845664a0122a24d2a12279c0febd744214c7167e7d9dea41330e107" + "8e38950b0929b8fbe662dd796c4c445285f91b37df3d40b83b4685347e5aa3aa" ], [ [ @@ -333,7 +333,7 @@ "file", "../out/sdk/wasp/universal/types.ts" ], - "791cb40cb5c405ade34d46770a8178353257e8d2351a877b6ca5e88aafb0ec13" + "be0d749bf9ae2f44ca2c281e0fb65c4d30c1d07e375ba38407e6c4fa1f05cc87" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/server/operations/wrappers.d.ts index 45073a49a..f13bf61ca 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { _Entity, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** * Constructs the unauthenticated operation's server-side API type from its @@ -24,9 +24,10 @@ export declare function createUnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/server/operations/wrappers.ts index 1a3daaf47..6026521f1 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { _Entity, @@ -54,6 +54,7 @@ export function createUnauthenticatedOperation< return operation as UnauthenticatedOperationFor } +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -62,13 +63,20 @@ export function createUnauthenticatedOperation< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/build/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts index 45073a49a..f13bf61ca 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { _Entity, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** * Constructs the unauthenticated operation's server-side API type from its @@ -24,9 +24,10 @@ export declare function createUnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/server/operations/wrappers.ts index 1a3daaf47..6026521f1 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { _Entity, @@ -54,6 +54,7 @@ export function createUnauthenticatedOperation< return operation as UnauthenticatedOperationFor } +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -62,13 +63,20 @@ export function createUnauthenticatedOperation< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/.wasp/out/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/.waspchecksums index 94fe2e28e..a22c9cd9e 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/.waspchecksums @@ -102,7 +102,7 @@ "file", "../out/sdk/wasp/client/operations/rpc.ts" ], - "63fb0670b2ccff4ad005bbb76597572a60e01f31b739d7bc764bb59c4f3c53d4" + "08f30fe4e31a691a225949ccd4d638cffe78bf2f4f2a76feb70133d4d9a5ba94" ], [ [ @@ -305,7 +305,7 @@ "file", "../out/sdk/wasp/server/operations/wrappers.ts" ], - "4f3ffd00d845664a0122a24d2a12279c0febd744214c7167e7d9dea41330e107" + "8e38950b0929b8fbe662dd796c4c445285f91b37df3d40b83b4685347e5aa3aa" ], [ [ @@ -333,7 +333,7 @@ "file", "../out/sdk/wasp/universal/types.ts" ], - "791cb40cb5c405ade34d46770a8178353257e8d2351a877b6ca5e88aafb0ec13" + "be0d749bf9ae2f44ca2c281e0fb65c4d30c1d07e375ba38407e6c4fa1f05cc87" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts index 45073a49a..f13bf61ca 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { _Entity, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** * Constructs the unauthenticated operation's server-side API type from its @@ -24,9 +24,10 @@ export declare function createUnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/server/operations/wrappers.ts index 1a3daaf47..6026521f1 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { _Entity, @@ -54,6 +54,7 @@ export function createUnauthenticatedOperation< return operation as UnauthenticatedOperationFor } +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -62,13 +63,20 @@ export function createUnauthenticatedOperation< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/.wasp/out/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums index fbe7d302f..b9ab1d31d 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums @@ -305,7 +305,7 @@ "file", "../out/sdk/wasp/client/operations/rpc.ts" ], - "63fb0670b2ccff4ad005bbb76597572a60e01f31b739d7bc764bb59c4f3c53d4" + "08f30fe4e31a691a225949ccd4d638cffe78bf2f4f2a76feb70133d4d9a5ba94" ], [ [ @@ -725,7 +725,7 @@ "file", "../out/sdk/wasp/server/operations/wrappers.ts" ], - "d2ae69bd910aa1238c6f87a6d4f6ca88e187935059820a8bd3860cbc9f5e1d3b" + "3ca438a1f9e44d7391de91c6e923d19e638932d079922a73b6d4d683e0509f11" ], [ [ @@ -753,7 +753,7 @@ "file", "../out/sdk/wasp/universal/types.ts" ], - "791cb40cb5c405ade34d46770a8178353257e8d2351a877b6ca5e88aafb0ec13" + "be0d749bf9ae2f44ca2c281e0fb65c4d30c1d07e375ba38407e6c4fa1f05cc87" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/crud/operationsHelpers.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/crud/operationsHelpers.d.ts index c0bbec7c1..0286482af 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/crud/operationsHelpers.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/crud/operationsHelpers.d.ts @@ -2,4 +2,4 @@ import type { Query, Action } from "../operations/rpc"; export declare function makeUseQueryFor(query: Query): (queryFnArgs?: Input, options?: any) => import("@tanstack/react-query").UseQueryResult; export declare function makeUseActionFor(action: Action): (actionOptions?: { optimisticUpdates: import("../operations").OptimisticUpdateDefinition[]; -}) => [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +}) => import("../../universal/types").IfAny Promise, [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise>; diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts index 85c2918f5..29ad9444a 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { type AuthUser } from 'wasp/auth'; import { _Entity, AuthenticatedOperationDefinition, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** @@ -49,7 +49,10 @@ export declare function createAuthenticatedOperation = [ +type AuthenticatedOperation = IfAny Promise, AuthenticatedOperationWithNonAnyInput>; +type AuthenticatedOperationWithNonAnyInput = [ Input ] extends [never] ? (args: unknown, context: { user: AuthUser; @@ -71,9 +74,10 @@ type GenericAuthenticatedOperationDefinition = AuthenticatedOperationDefinition< * `void` if the operation doesn't expect a payload). * @template Output The type of the operation's return value. */ -type UnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/operations/wrappers.ts index c20fd751d..be95eec57 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { type AuthUser } from 'wasp/auth' import { @@ -154,6 +154,9 @@ function includesPayload( type AuthenticatedOperationArgsFor = Parameters> +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before attempting to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 /** * Constructs the type for an authenticated operation's server-side API. * @@ -162,6 +165,14 @@ type AuthenticatedOperationArgsFor = + IfAny< + Input, + (args: any, context: { user: AuthUser }) => Promise, + AuthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type AuthenticatedOperationWithNonAnyInput = [Input] extends [never] ? (args: unknown, context: { user: AuthUser }) => Promise : [Input] extends [void] @@ -180,6 +191,7 @@ type GenericAuthenticatedOperationDefinition = AuthenticatedOperationDefinition< Payload > +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -188,13 +200,20 @@ type GenericAuthenticatedOperationDefinition = AuthenticatedOperationDefinition< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/.waspchecksums index e04366206..601eff238 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/.waspchecksums @@ -102,7 +102,7 @@ "file", "../out/sdk/wasp/client/operations/rpc.ts" ], - "63fb0670b2ccff4ad005bbb76597572a60e01f31b739d7bc764bb59c4f3c53d4" + "08f30fe4e31a691a225949ccd4d638cffe78bf2f4f2a76feb70133d4d9a5ba94" ], [ [ @@ -361,7 +361,7 @@ "file", "../out/sdk/wasp/server/operations/wrappers.ts" ], - "4f3ffd00d845664a0122a24d2a12279c0febd744214c7167e7d9dea41330e107" + "8e38950b0929b8fbe662dd796c4c445285f91b37df3d40b83b4685347e5aa3aa" ], [ [ @@ -389,7 +389,7 @@ "file", "../out/sdk/wasp/universal/types.ts" ], - "791cb40cb5c405ade34d46770a8178353257e8d2351a877b6ca5e88aafb0ec13" + "be0d749bf9ae2f44ca2c281e0fb65c4d30c1d07e375ba38407e6c4fa1f05cc87" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts index 45073a49a..f13bf61ca 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { _Entity, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** * Constructs the unauthenticated operation's server-side API type from its @@ -24,9 +24,10 @@ export declare function createUnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/server/operations/wrappers.ts index 1a3daaf47..6026521f1 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { _Entity, @@ -54,6 +54,7 @@ export function createUnauthenticatedOperation< return operation as UnauthenticatedOperationFor } +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -62,13 +63,20 @@ export function createUnauthenticatedOperation< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/.wasp/out/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/.waspchecksums index ab5f1d500..672f45836 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/.waspchecksums @@ -102,7 +102,7 @@ "file", "../out/sdk/wasp/client/operations/rpc.ts" ], - "63fb0670b2ccff4ad005bbb76597572a60e01f31b739d7bc764bb59c4f3c53d4" + "08f30fe4e31a691a225949ccd4d638cffe78bf2f4f2a76feb70133d4d9a5ba94" ], [ [ @@ -305,7 +305,7 @@ "file", "../out/sdk/wasp/server/operations/wrappers.ts" ], - "4f3ffd00d845664a0122a24d2a12279c0febd744214c7167e7d9dea41330e107" + "8e38950b0929b8fbe662dd796c4c445285f91b37df3d40b83b4685347e5aa3aa" ], [ [ @@ -333,7 +333,7 @@ "file", "../out/sdk/wasp/universal/types.ts" ], - "791cb40cb5c405ade34d46770a8178353257e8d2351a877b6ca5e88aafb0ec13" + "be0d749bf9ae2f44ca2c281e0fb65c4d30c1d07e375ba38407e6c4fa1f05cc87" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/client/operations/rpc.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/client/operations/rpc.ts index 4d8354686..4775639ef 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/client/operations/rpc.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/client/operations/rpc.ts @@ -1,5 +1,6 @@ import { type Route } from "wasp/client"; import type { + IfAny, _Awaited, _ReturnType, } from "wasp/universal/types" @@ -55,11 +56,11 @@ export type QueryMetadata = { */ export type OperationRpcFor = Parameters extends [] - ? ClientOperation>> - : ClientOperation< - Parameters[0], - _Awaited<_ReturnType> - > + ? ClientOperation>> + : ClientOperation< + Parameters[0], + _Awaited<_ReturnType> + > // PRIVATE API (needed in SDK) /** @@ -74,8 +75,21 @@ export type GenericBackendOperation = (args: never, context: any) => unknown */ export type GenericOperationRpc = (args: never) => Promise +// NOTE: There's some duplication in the below types. +// Read the discussion here to understand why before trying to remove it: +// https://github.com/wasp-lang/wasp/pull/2170#discussion_r1671285049 +// +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 +type ClientOperation = + IfAny< + Input, + (args?: any) => Promise, + ClientOperationWithNonAnyInput + > + // Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 -type ClientOperation = [Input] extends [never] +type ClientOperationWithNonAnyInput = + [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts index 0058d552d..8a73d6c66 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/client/operations/rpc.d.ts @@ -1,5 +1,5 @@ import { type Route } from "wasp/client"; -import type { _Awaited, _ReturnType } from "wasp/universal/types"; +import type { IfAny, _Awaited, _ReturnType } from "wasp/universal/types"; /** * The client Query object type. It's a callable Query function with some extra * properties (metadata). @@ -34,5 +34,8 @@ export type GenericBackendOperation = (args: never, context: any) => unknown; * A supertype of all possible frontend RPC function types. */ export type GenericOperationRpc = (args: never) => Promise; -type ClientOperation = [Input] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +type ClientOperation = IfAny Promise, ClientOperationWithNonAnyInput>; +type ClientOperationWithNonAnyInput = [ + Input +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; export {}; diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts index 45073a49a..f13bf61ca 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/server/operations/wrappers.d.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types'; +import { IfAny, _Awaited, _ReturnType } from '../../universal/types'; import { _Entity, UnauthenticatedOperationDefinition, Payload } from '../_types'; /** * Constructs the unauthenticated operation's server-side API type from its @@ -24,9 +24,10 @@ export declare function createUnauthenticatedOperation = [ +type UnauthenticatedOperation = IfAny Promise, UnauthenticatedOperationWithNonAnyInput>; +type UnauthenticatedOperationWithNonAnyInput = [ Input -] extends [never] ? (args: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; +] extends [never] ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise; /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/universal/types.d.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/universal/types.d.ts index ceed57cc3..f92092c8c 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/universal/types.d.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/dist/universal/types.d.ts @@ -4,3 +4,4 @@ export type Expand = T extends (...args: infer A) => infer R ? (...args: A) = export type _Awaited = T extends Promise ? _Awaited : T; export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never; export type Tail = T extends [unknown, ...infer R] ? R : never; +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/server/operations/wrappers.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/server/operations/wrappers.ts index 1a3daaf47..6026521f1 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/server/operations/wrappers.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/server/operations/wrappers.ts @@ -1,4 +1,4 @@ -import { _Awaited, _ReturnType } from '../../universal/types' +import { IfAny, _Awaited, _ReturnType } from '../../universal/types' import { _Entity, @@ -54,6 +54,7 @@ export function createUnauthenticatedOperation< return operation as UnauthenticatedOperationFor } +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/2170#issue-2398830273 /** * Constructs the type for an unauthenticated operation's server-side API. * @@ -62,13 +63,20 @@ export function createUnauthenticatedOperation< * @template Output The type of the operation's return value. */ type UnauthenticatedOperation = + IfAny< + Input, + (args?: any) => Promise, + UnauthenticatedOperationWithNonAnyInput + > + +// Read this to understand the type: https://github.com/wasp-lang/wasp/pull/1090#discussion_r1159732471 +type UnauthenticatedOperationWithNonAnyInput = [Input] extends [never] - ? (args: unknown) => Promise + ? (args?: unknown) => Promise : [Input] extends [void] ? () => Promise : (args: Input) => Promise - /** * The principal type for an unauthenticated operation's definition (i.e., all * unauthenticated operation definition types are a subtype of this type). diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/universal/types.ts b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/universal/types.ts index d84e38d09..46077a0e2 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/universal/types.ts +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/.wasp/out/sdk/wasp/universal/types.ts @@ -27,9 +27,13 @@ export type _Awaited = T extends Promise // TODO: investigate how to properly specify the 'extends' constraint for function // type (i.e., any vs never and unknown) and stick with that. Take DX into // consideration. -export type _ReturnType unknown> = +export type _ReturnType unknown> = T extends (...args: never[]) => infer R ? R : never // Returns elements of an array except the first one. export type Tail = T extends [unknown, ...infer R] ? R : never; + + +// Source: https://stackoverflow.com/a/55541672 +export type IfAny = 0 extends (1 & Value) ? Then : Else; diff --git a/waspc/examples/todoApp/main.wasp b/waspc/examples/todoApp/main.wasp index ebc6fb245..88219c23e 100644 --- a/waspc/examples/todoApp/main.wasp +++ b/waspc/examples/todoApp/main.wasp @@ -220,6 +220,7 @@ job mySpecialScheduledJob { } // --------- Testing --------- // + action testingAction { fn: import { testingAction } from "@src/testTypes/operations/server", entities: [] @@ -229,8 +230,16 @@ query getDate { fn: import { getDate } from "@src/testTypes/operations/definitions" } -query getAnything { - fn: import { getAnything } from "@src/testTypes/operations/definitions", + +query getAnythingNoAuth { + fn: import { getAnythingNoAuth } from "@src/testTypes/operations/definitions", + auth: false, + entities: [] +} + +query getAnythingAuth { + fn: import { getAnythingAuth } from "@src/testTypes/operations/definitions", + auth: true, entities: [] } @@ -239,6 +248,25 @@ query getTrueVoid { entities: [] } +query getAnyNoAuth { + fn: import { getAnyNoAuth } from "@src/testTypes/operations/definitions", + auth: false, + entities: [] +} + +query getAnyAuth { + fn: import { getAnyAuth } from "@src/testTypes/operations/definitions", + auth: true, + entities: [] +} + +query getAnyToNumberSpecified { + fn: import { getAnyToNumberSpecified } from "@src/testTypes/operations/definitions", + auth: true, + entities: [] +} + + action taskToTaskUnspecified { fn: import { taskToTaskUnspecified } from "@src/testTypes/operations/definitions", entities: [Task] diff --git a/waspc/examples/todoApp/src/Todo.tsx b/waspc/examples/todoApp/src/Todo.tsx index f23495a54..00ce39bd2 100644 --- a/waspc/examples/todoApp/src/Todo.tsx +++ b/waspc/examples/todoApp/src/Todo.tsx @@ -12,7 +12,7 @@ import { getTasks, getTask, getDate, - getAnything, + getAnythingAuth, } from 'wasp/client/operations' import React, { useState, FormEventHandler, ChangeEventHandler } from 'react' @@ -259,7 +259,7 @@ async function logAll() { const date = await getDate() console.info('Got date:', date) - const anything = await getAnything() + const anything = await getAnythingAuth() console.info('Got anything:', anything) } diff --git a/waspc/examples/todoApp/src/testTypes/operations/client.ts b/waspc/examples/todoApp/src/testTypes/operations/client.ts index 5d2391195..43a422b18 100644 --- a/waspc/examples/todoApp/src/testTypes/operations/client.ts +++ b/waspc/examples/todoApp/src/testTypes/operations/client.ts @@ -2,7 +2,7 @@ import { AuthUser } from 'wasp/auth' import { getMe } from 'wasp/client/auth' import { getDate, - getAnything, + getAnythingAuth, getTrueVoid, voidToStringAuth, voidToStringNoAuth, @@ -14,6 +14,10 @@ import { taskToTaskUnspecified, taskToTaskSatisfies, taskToTaskSpecified, + getAnyAuth, + getAnyNoAuth, + getAnyToNumberSpecified, + getAnythingNoAuth, } from 'wasp/client/operations' import { @@ -54,10 +58,19 @@ type TestCases = [ Expect Promise)>>, Expect< Equal< - typeof getAnything, + typeof getAnythingAuth, + QueryMetadata & ((args?: unknown) => Promise) + > + >, + Expect< + Equal< + typeof getAnythingNoAuth, QueryMetadata & ((args?: unknown) => Promise) > >, Expect Promise)>>, - Expect Promise)>> + Expect Promise)>>, + Expect Promise)>>, + Expect Promise)>>, + Expect Promise)>>, ] diff --git a/waspc/examples/todoApp/src/testTypes/operations/definitions.ts b/waspc/examples/todoApp/src/testTypes/operations/definitions.ts index 016a2b7ed..45a27876f 100644 --- a/waspc/examples/todoApp/src/testTypes/operations/definitions.ts +++ b/waspc/examples/todoApp/src/testTypes/operations/definitions.ts @@ -7,8 +7,10 @@ import type { TaskToTaskSatisfies, TaskToTaskSpecified, GetDate, - GetAnything, + GetAnythingAuth, + GetAnythingNoAuth, GetTrueVoid, + GetAnyToNumberSpecified, } from 'wasp/server/operations' export const taskToTaskUnspecified = async (args: Task) => args @@ -47,7 +49,7 @@ export const voidToStringNoAuth: VoidToStringNoAuth = async ( return 'void' } -export const unspecifiedToNumber = (async (args) => { +export const unspecifiedToNumber = (async (_args) => { return 10 }) satisfies UnspecifiedToNumber @@ -101,10 +103,27 @@ export const getDate: GetDate = async () => { return new Date() } -export const getAnything: GetAnything = async () => { +export const getAnythingAuth: GetAnythingAuth = async () => { return 'anything' } +export const getAnythingNoAuth: GetAnythingNoAuth = async () => { + return 'anything' +} + + export const getTrueVoid = (async () => { return 'anything' }) satisfies GetTrueVoid + +export const getAnyNoAuth = (_args: any, _context: any): any => { + return 'anything' +} + +export const getAnyAuth = (_args: any, _context: any): any => { + return 'anything' +} + +export const getAnyToNumberSpecified: GetAnyToNumberSpecified = (_args, _context) => { + return 10 +} diff --git a/waspc/examples/todoApp/src/testTypes/operations/server.ts b/waspc/examples/todoApp/src/testTypes/operations/server.ts index 38b90cc4f..2c58081fc 100644 --- a/waspc/examples/todoApp/src/testTypes/operations/server.ts +++ b/waspc/examples/todoApp/src/testTypes/operations/server.ts @@ -9,7 +9,13 @@ import { taskToTaskUnspecified, taskToTaskSatisfies, taskToTaskSpecified, + getAnythingAuth, + getAnythingNoAuth, + getTrueVoid, + getAnyNoAuth, type TestingAction, + getAnyAuth, + getAnyToNumberSpecified, } from 'wasp/server/operations' import { @@ -20,9 +26,10 @@ import { import { Equal, Expect } from '../helpers' import { AuthUser } from 'wasp/auth' import { Task } from 'wasp/entities' +import { Payload } from 'wasp/server/_types' -export const testingAction: TestingAction = async (args, context) => { - // todo(filip): When sorting out the tests, we should also test whether the +export const testingAction: TestingAction = async (_args, context) => { + // TODO: (Filip) When sorting out the tests, we should also test whether the // outputs are correct. See: // - https://github.com/wasp-lang/wasp/issues/2024 // - https://github.com/wasp-lang/wasp/issues/2011 @@ -42,7 +49,7 @@ export const testingAction: TestingAction = async (args, context) => { } type TestCases = [ - // todo(filip): Prisma errors casuing this test to fail, try to add Except + // TODO: (FILIP) Prisma errors casuing this test to fail, try to add Except // after updating Prisma: https://github.com/wasp-lang/wasp/issues/2099 Equal< typeof taskToTaskUnspecified, @@ -51,7 +58,7 @@ type TestCases = [ ctx: { user: AuthUser } ) => ReturnType >, - // todo(filip): Prisma errors casuing this test to fail, try to add Except + // TODO: (FILIP) Prisma errors casuing this test to fail, try to add Except // after updating Prisma: https://github.com/wasp-lang/wasp/issues/2099 Equal< typeof taskToTaskSatisfies, @@ -91,5 +98,21 @@ type TestCases = [ typeof boolToVoidAuth, (payload: boolean, ctx: { user: AuthUser }) => Promise > - > + >, + Expect< + Equal< + typeof getAnythingAuth, + (args: unknown, ctx: { user: AuthUser }) => Promise + > + >, + Expect< + Equal< + typeof getAnythingNoAuth, + (args?: unknown) => Promise + > + >, + Expect Promise>>, + Expect Promise>>, + Expect Promise>>, + Expect Promise>>, ]