Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes CRUD feature to work with SDK #1656

Merged
merged 11 commits into from
Jan 25, 2024
Merged
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{{={= =}=}}
import { createAction } from "../actions/core";
import { useAction } from "../actions";
import { createQuery } from "../queries/core";
import { useQuery } from "../queries";
import { createAction } from "wasp/rpc/actions/core";
import { useAction } from "wasp/rpc";
import { createQuery } from "wasp/rpc/queries/core";
import { useQuery } from "wasp/rpc";
import {
{=# operations.Get =}
GetQueryResolved,
Expand All @@ -19,7 +19,7 @@ import {
{=# operations.Delete =}
DeleteActionResolved,
{=/ operations.Delete =}
} from '../../../server/src/crud/{= name =}'
} from 'wasp/server/crud/{= name =}'

function createCrud() {
{=# operations.Get =}
Expand Down
7 changes: 7 additions & 0 deletions waspc/data/Generator/templates/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@
"./rpc": "./dist/rpc/index.js",
{=! Used by users, documented. =}
"./rpc/queries": "./dist/rpc/queries/index.js",
{=! Used by our code, uncodumented (but accessible) for users. =}
"./rpc/queries/core": "./dist/rpc/queries/core.js",
{=! Used by users, documented. =}
"./rpc/actions": "./dist/rpc/actions/index.js",
{=! Used by our code, uncodumented (but accessible) for users. =}
"./rpc/actions/core": "./dist/rpc/actions/core.js",
{=! Used by our code, uncodumented (but accessible) for users. =}
"./rpc/queryClient": "./dist/rpc/queryClient.js",
{=! Used by users, documented. =}
"./types": "./dist/types/index.js",
Expand Down Expand Up @@ -117,6 +121,9 @@
{=! Used by users, documented. =}
"./dbSeed/types": "./dist/dbSeed/types.js",
{=! Used by users, documented. =}
"./crud/*": "./dist/crud/*.js",
{=! Used by our code, uncodumented (but accessible) for users. =}
"./server/crud/*": "./dist/server/crud/*",
"./email": "./dist/email/index.js",
{=! Used by our code, uncodumented (but accessible) for users. =}
"./email/core/types": "./dist/email/core/types.js",
Expand Down
105 changes: 105 additions & 0 deletions waspc/data/Generator/templates/sdk/server/crud/_operationTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{{={= =}=}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generate server crud types in the SDK so they can be used for full-stack type safety.

import type {
{=# isAuthEnabled =}
AuthenticatedAction,
AuthenticatedQuery,
{=/ isAuthEnabled =}
{=^ isAuthEnabled =}
Action,
Query,
{=/ isAuthEnabled =}
_{= crud.entityUpper =},
} from "wasp/server/_types";
import type { Prisma } from "@prisma/client";
import { Payload } from "wasp/server/_types/serialization";
import type {
{= crud.entityUpper =},
} from "wasp/entities";
{=# overrides.GetAll.isDefined =}
{=& overrides.GetAll.importStatement =}
{=/ overrides.GetAll.isDefined =}
{=# overrides.Get.isDefined =}
{=& overrides.Get.importStatement =}
{=/ overrides.Get.isDefined =}
{=# overrides.Create.isDefined =}
{=& overrides.Create.importStatement =}
{=/ overrides.Create.isDefined =}
{=# overrides.Update.isDefined =}
{=& overrides.Update.importStatement =}
{=/ overrides.Update.isDefined =}
{=# overrides.Delete.isDefined =}
{=& overrides.Delete.importStatement =}
{=/ overrides.Delete.isDefined =}

type _WaspEntityTagged = _{= crud.entityUpper =}
type _WaspEntity = {= crud.entityUpper =}

{=# crud.operations.GetAll =}
// Get All query
export type GetAllQuery<Input extends Payload, Output extends Payload> = {= queryType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.GetAll.isDefined =}
type GetAllInput = {}
type GetAllOutput = _WaspEntity[]
export type GetAllQueryResolved = GetAllQuery<GetAllInput, GetAllOutput>
{=/ overrides.GetAll.isDefined =}
{=# overrides.GetAll.isDefined =}
const _waspGetAllQuery = {= overrides.GetAll.importIdentifier =}
export type GetAllQueryResolved = typeof _waspGetAllQuery
{=/ overrides.GetAll.isDefined =}
{=/ crud.operations.GetAll =}

{=# crud.operations.Get =}
// Get query
export type GetQuery<Input extends Payload, Output extends Payload> = {= queryType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Get.isDefined =}
type GetInput = Prisma.{= crud.entityUpper =}WhereUniqueInput
type GetOutput = _WaspEntity | null
export type GetQueryResolved = GetQuery<GetInput, GetOutput>
{=/ overrides.Get.isDefined =}
{=# overrides.Get.isDefined =}
const _waspGetQuery = {= overrides.Get.importIdentifier =}
export type GetQueryResolved = typeof _waspGetQuery
{=/ overrides.Get.isDefined =}
{=/ crud.operations.Get =}

{=# crud.operations.Create =}
// Create action
export type CreateAction<Input extends Payload, Output extends Payload>= {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Create.isDefined =}
type CreateInput = Prisma.{= crud.entityUpper =}CreateInput
type CreateOutput = _WaspEntity
export type CreateActionResolved = CreateAction<CreateInput, CreateOutput>
{=/ overrides.Create.isDefined =}
{=# overrides.Create.isDefined =}
const _waspCreateAction = {= overrides.Create.importIdentifier =}
export type CreateActionResolved = typeof _waspCreateAction
{=/ overrides.Create.isDefined =}
{=/ crud.operations.Create =}

{=# crud.operations.Update =}
// Update action
export type UpdateAction<Input extends Payload, Output extends Payload> = {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Update.isDefined =}
type UpdateInput = Prisma.{= crud.entityUpper =}UpdateInput & Prisma.{= crud.entityUpper =}WhereUniqueInput
type UpdateOutput = _WaspEntity
export type UpdateActionResolved = UpdateAction<UpdateInput, UpdateOutput>
{=/ overrides.Update.isDefined =}
{=# overrides.Update.isDefined =}
const _waspUpdateAction = {= overrides.Update.importIdentifier =}
export type UpdateActionResolved = typeof _waspUpdateAction
{=/ overrides.Update.isDefined =}
{=/ crud.operations.Update =}

{=# crud.operations.Delete =}
// Delete action
export type DeleteAction<Input extends Payload, Output extends Payload> = {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Delete.isDefined =}
type DeleteInput = Prisma.{= crud.entityUpper =}WhereUniqueInput
type DeleteOutput = _WaspEntity
export type DeleteActionResolved = DeleteAction<DeleteInput, DeleteOutput>
{=/ overrides.Delete.isDefined =}
{=# overrides.Delete.isDefined =}
const _waspDeleteAction = {= overrides.Delete.importIdentifier =}
export type DeleteActionResolved = typeof _waspDeleteAction
{=/ overrides.Delete.isDefined =}
{=/ crud.operations.Delete =}
44 changes: 5 additions & 39 deletions waspc/data/Generator/templates/server/src/crud/_operations.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
{{={= =}=}}
import prisma from "wasp/server/dbClient";

import type {
{=# isAuthEnabled =}
AuthenticatedAction,
AuthenticatedQuery,
{=/ isAuthEnabled =}
{=^ isAuthEnabled =}
Action,
Query,
{=/ isAuthEnabled =}
_{= crud.entityUpper =},
} from "../_types";
import type { Prisma } from "@prisma/client";
import { Payload } from "../_types/serialization.js";
import type {
{= crud.entityUpper =},
} from "../entities";
} from "wasp/entities";
{=# isAuthEnabled =}
import { throwInvalidCredentialsError } from '../auth/utils.js'
import { throwInvalidCredentialsError } from 'wasp/auth/utils'
{=/ isAuthEnabled =}
import type { GetAllQuery, GetQuery, CreateAction, UpdateAction, DeleteAction } from "{= crudTypesImportPath =}";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are importing the CRUD types from the SDK

{=# overrides.GetAll.isDefined =}
{=& overrides.GetAll.importStatement =}
{=/ overrides.GetAll.isDefined =}
Expand All @@ -36,7 +25,6 @@ import { throwInvalidCredentialsError } from '../auth/utils.js'
{=& overrides.Delete.importStatement =}
{=/ overrides.Delete.isDefined =}

type _WaspEntityTagged = _{= crud.entityUpper =}
type _WaspEntity = {= crud.entityUpper =}
const entities = {
{= crud.entityUpper =}: prisma.{= crud.entityLower =},
Expand All @@ -48,12 +36,7 @@ const entities = {
{=# crud.operations.GetAll =}
// Get All query
{=!
// 1. We define the type for the operation using "queryType" template variable which is either
// AuthenticatedQuery or Query (it depends on whether auth is enabled or not).
=}
export type GetAllQuery<Input extends Payload, Output extends Payload> = {= queryType =}<[_WaspEntityTagged], Input, Output>
{=!
// 2. Then, we either use the default implementation of the operation...
// 1. We either use the default implementation of the operation...
=}
{=^ overrides.GetAll.isDefined =}
type GetAllInput = {}
Expand All @@ -74,13 +57,7 @@ const _waspGetAllQuery = {= overrides.GetAll.importIdentifier =}
{=/ overrides.GetAll.isDefined =}

{=!
// 3. We then define the final type for the operation, which is the type of the function we defined in the previous step.
// It will pick up either the default implementation or the one from the overrides.
=}
export type GetAllQueryResolved = typeof _waspGetAllQuery

{=!
// 4. We define a function that is used as the Express route handler
// 2. We define a function that is used as the Express route handler
=}
export async function getAllFn(args, context) {
return (_waspGetAllQuery as any)(args, {
Expand All @@ -95,7 +72,6 @@ export async function getAllFn(args, context) {

{=# crud.operations.Get =}
// Get query
export type GetQuery<Input extends Payload, Output extends Payload> = {= queryType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Get.isDefined =}
type GetInput = Prisma.{= crud.entityUpper =}WhereUniqueInput
type GetOutput = _WaspEntity | null
Expand All @@ -109,7 +85,6 @@ const _waspGetQuery: GetQuery<GetInput, GetOutput> = ((args, context) => {
{=# overrides.Get.isDefined =}
const _waspGetQuery = {= overrides.Get.importIdentifier =}
{=/ overrides.Get.isDefined =}
export type GetQueryResolved = typeof _waspGetQuery

export async function getFn(args, context) {
return (_waspGetQuery as any)(args, {
Expand All @@ -121,7 +96,6 @@ export async function getFn(args, context) {

{=# crud.operations.Create =}
// Create action
export type CreateAction<Input extends Payload, Output extends Payload>= {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Create.isDefined =}
type CreateInput = Prisma.{= crud.entityUpper =}CreateInput
type CreateOutput = _WaspEntity
Expand All @@ -136,8 +110,6 @@ const _waspCreateAction: CreateAction<CreateInput, CreateOutput> = ((args, conte
const _waspCreateAction = {= overrides.Create.importIdentifier =}
{=/ overrides.Create.isDefined =}

export type CreateActionResolved = typeof _waspCreateAction

export async function createFn(args, context) {
return (_waspCreateAction as any)(args, {
...context,
Expand All @@ -148,7 +120,6 @@ export async function createFn(args, context) {

{=# crud.operations.Update =}
// Update action
export type UpdateAction<Input extends Payload, Output extends Payload> = {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Update.isDefined =}
type UpdateInput = Prisma.{= crud.entityUpper =}UpdateInput & Prisma.{= crud.entityUpper =}WhereUniqueInput
type UpdateOutput = _WaspEntity
Expand All @@ -167,8 +138,6 @@ const _waspUpdateAction: UpdateAction<UpdateInput, UpdateOutput> = ((args, conte
const _waspUpdateAction = {= overrides.Update.importIdentifier =}
{=/ overrides.Update.isDefined =}

export type UpdateActionResolved = typeof _waspUpdateAction

export async function updateFn(args, context) {
return (_waspUpdateAction as any)(args, {
...context,
Expand All @@ -179,7 +148,6 @@ export async function updateFn(args, context) {

{=# crud.operations.Delete =}
// Delete action
export type DeleteAction<Input extends Payload, Output extends Payload> = {= actionType =}<[_WaspEntityTagged], Input, Output>
{=^ overrides.Delete.isDefined =}
type DeleteInput = Prisma.{= crud.entityUpper =}WhereUniqueInput
type DeleteOutput = _WaspEntity
Expand All @@ -195,8 +163,6 @@ const _waspDeleteAction: DeleteAction<DeleteInput, DeleteOutput> = ((args, conte
const _waspDeleteAction = {= overrides.Delete.importIdentifier =}
{=/ overrides.Delete.isDefined =}

export type DeleteActionResolved = typeof _waspDeleteAction

export async function deleteFn(args, context) {
return (_waspDeleteAction as any)(args, {
...context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"./core/auth": "./dist/core/auth.js",
"./rpc": "./dist/rpc/index.js",
"./rpc/queries": "./dist/rpc/queries/index.js",
"./rpc/queries/core": "./dist/rpc/queries/core.js",
"./rpc/actions": "./dist/rpc/actions/index.js",
"./rpc/actions/core": "./dist/rpc/actions/core.js",
"./rpc/queryClient": "./dist/rpc/queryClient.js",
"./types": "./dist/types/index.js",
"./auth": "./dist/auth/index.js",
Expand Down Expand Up @@ -59,6 +61,8 @@
"./server/queries": "./dist/server/queries/index.js",
"./server/auth/email": "./dist/server/auth/email/index.js",
"./dbSeed/types": "./dist/dbSeed/types.js",
"./crud/*": "./dist/crud/*.js",
"./server/crud/*": "./dist/server/crud/*",
"./email": "./dist/email/index.js",
"./email/core/types": "./dist/email/core/types.js",
"./server/auth/email/utils": "./dist/server/auth/email/utils.js",
Expand Down
13 changes: 13 additions & 0 deletions waspc/examples/todo-typescript/main.wasp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ entity Task {=psl
userId Int
psl=}

crud Tasks {
entity: Task,
operations: {
getAll: {
overrideFn: import { getAllQuery } from "@src/task/crud.js",
},
create: {},
update: {},
get: {},
delete: {}
}
}

route RootRoute { path: "/", to: MainPage }
page MainPage {
authRequired: true,
Expand Down
Loading
Loading