@zenstackhq/server 2.21.0 → 3.0.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +1 -1
  2. package/dist/api.cjs +299 -0
  3. package/dist/api.cjs.map +1 -0
  4. package/dist/api.d.cts +28 -0
  5. package/dist/api.d.ts +28 -0
  6. package/dist/api.js +264 -0
  7. package/dist/api.js.map +1 -0
  8. package/dist/express.cjs +75 -0
  9. package/dist/express.cjs.map +1 -0
  10. package/dist/express.d.cts +31 -0
  11. package/dist/express.d.ts +31 -0
  12. package/dist/express.js +50 -0
  13. package/dist/express.js.map +1 -0
  14. package/dist/types-BH-88xJo.d.cts +68 -0
  15. package/dist/types-BH-88xJo.d.ts +68 -0
  16. package/package.json +57 -58
  17. package/README.md +0 -5
  18. package/api/base.d.ts +0 -49
  19. package/api/base.js +0 -19
  20. package/api/base.js.map +0 -1
  21. package/api/index.d.ts +0 -2
  22. package/api/index.js +0 -8
  23. package/api/index.js.map +0 -1
  24. package/api/rest/index.d.ts +0 -34
  25. package/api/rest/index.js +0 -1598
  26. package/api/rest/index.js.map +0 -1
  27. package/api/rpc/index.d.ts +0 -4
  28. package/api/rpc/index.js +0 -248
  29. package/api/rpc/index.js.map +0 -1
  30. package/api/utils.d.ts +0 -8
  31. package/api/utils.js +0 -54
  32. package/api/utils.js.map +0 -1
  33. package/elysia/handler.d.ts +0 -44
  34. package/elysia/handler.js +0 -62
  35. package/elysia/handler.js.map +0 -1
  36. package/elysia/index.d.ts +0 -1
  37. package/elysia/index.js +0 -18
  38. package/elysia/index.js.map +0 -1
  39. package/express/index.d.ts +0 -2
  40. package/express/index.js +0 -21
  41. package/express/index.js.map +0 -1
  42. package/express/middleware.d.ts +0 -27
  43. package/express/middleware.js +0 -58
  44. package/express/middleware.js.map +0 -1
  45. package/fastify/index.d.ts +0 -2
  46. package/fastify/index.js +0 -21
  47. package/fastify/index.js.map +0 -1
  48. package/fastify/plugin.d.ts +0 -18
  49. package/fastify/plugin.js +0 -48
  50. package/fastify/plugin.js.map +0 -1
  51. package/hono/handler.d.ts +0 -12
  52. package/hono/handler.js +0 -47
  53. package/hono/handler.js.map +0 -1
  54. package/hono/index.d.ts +0 -1
  55. package/hono/index.js +0 -18
  56. package/hono/index.js.map +0 -1
  57. package/nestjs/api-handler.service.d.ts +0 -15
  58. package/nestjs/api-handler.service.js +0 -72
  59. package/nestjs/api-handler.service.js.map +0 -1
  60. package/nestjs/index.d.ts +0 -3
  61. package/nestjs/index.js +0 -20
  62. package/nestjs/index.js.map +0 -1
  63. package/nestjs/interfaces/api-handler-options.interface.d.ts +0 -17
  64. package/nestjs/interfaces/api-handler-options.interface.js +0 -3
  65. package/nestjs/interfaces/api-handler-options.interface.js.map +0 -1
  66. package/nestjs/interfaces/index.d.ts +0 -2
  67. package/nestjs/interfaces/index.js +0 -19
  68. package/nestjs/interfaces/index.js.map +0 -1
  69. package/nestjs/interfaces/zenstack-module-options.interface.d.ts +0 -35
  70. package/nestjs/interfaces/zenstack-module-options.interface.js +0 -3
  71. package/nestjs/interfaces/zenstack-module-options.interface.js.map +0 -1
  72. package/nestjs/zenstack.constants.d.ts +0 -4
  73. package/nestjs/zenstack.constants.js +0 -8
  74. package/nestjs/zenstack.constants.js.map +0 -1
  75. package/nestjs/zenstack.module.d.ts +0 -12
  76. package/nestjs/zenstack.module.js +0 -61
  77. package/nestjs/zenstack.module.js.map +0 -1
  78. package/next/app-route-handler.d.ts +0 -16
  79. package/next/app-route-handler.js +0 -65
  80. package/next/app-route-handler.js.map +0 -1
  81. package/next/index.d.ts +0 -38
  82. package/next/index.js +0 -17
  83. package/next/index.js.map +0 -1
  84. package/next/pages-route-handler.d.ts +0 -9
  85. package/next/pages-route-handler.js +0 -45
  86. package/next/pages-route-handler.js.map +0 -1
  87. package/nuxt/handler.d.ts +0 -12
  88. package/nuxt/handler.js +0 -45
  89. package/nuxt/handler.js.map +0 -1
  90. package/nuxt/index.d.ts +0 -1
  91. package/nuxt/index.js +0 -18
  92. package/nuxt/index.js.map +0 -1
  93. package/shared.d.ts +0 -20
  94. package/shared.js +0 -50
  95. package/shared.js.map +0 -1
  96. package/sveltekit/handler.d.ts +0 -20
  97. package/sveltekit/handler.js +0 -68
  98. package/sveltekit/handler.js.map +0 -1
  99. package/sveltekit/index.d.ts +0 -2
  100. package/sveltekit/index.js +0 -21
  101. package/sveltekit/index.js.map +0 -1
  102. package/tanstack-start/handler.d.ts +0 -11
  103. package/tanstack-start/handler.js +0 -75
  104. package/tanstack-start/handler.js.map +0 -1
  105. package/tanstack-start/index.d.ts +0 -17
  106. package/tanstack-start/index.js +0 -16
  107. package/tanstack-start/index.js.map +0 -1
  108. package/types.d.ts +0 -49
  109. package/types.js +0 -3
  110. package/types.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/rpc/index.ts","../src/api/utils.ts"],"sourcesContent":["import { lowerCaseFirst, safeJSONStringify } from '@zenstackhq/common-helpers';\nimport {\n InputValidationError,\n NotFoundError,\n RejectedByPolicyError,\n ZenStackError,\n type ClientContract,\n} from '@zenstackhq/runtime';\nimport type { SchemaDef } from '@zenstackhq/runtime/schema';\nimport SuperJSON from 'superjson';\nimport type { ApiHandler, LogConfig, RequestContext, Response } from '../../types';\nimport { log, registerCustomSerializers } from '../utils';\n\nregisterCustomSerializers();\n\n/**\n * Options for {@link RPCApiHandler}\n */\nexport type RPCApiHandlerOptions<Schema extends SchemaDef> = {\n schema: Schema;\n log?: LogConfig;\n};\n\n/**\n * RPC style API request handler that mirrors the ZenStackClient API\n */\nexport class RPCApiHandler<Schema extends SchemaDef> implements ApiHandler<Schema> {\n constructor(private readonly options: RPCApiHandlerOptions<Schema>) {}\n\n get schema(): Schema {\n return this.options.schema;\n }\n\n async handleRequest({ client, method, path, query, requestBody }: RequestContext<Schema>): Promise<Response> {\n const parts = path.split('/').filter((p) => !!p);\n const op = parts.pop();\n let model = parts.pop();\n\n if (parts.length !== 0 || !op || !model) {\n return this.makeBadInputErrorResponse('invalid request path');\n }\n\n model = lowerCaseFirst(model);\n method = method.toUpperCase();\n let args: unknown;\n let resCode = 200;\n\n switch (op) {\n case 'create':\n case 'createMany':\n case 'createManyAndReturn':\n case 'upsert':\n if (method !== 'POST') {\n return this.makeBadInputErrorResponse('invalid request method, only POST is supported');\n }\n if (!requestBody) {\n return this.makeBadInputErrorResponse('missing request body');\n }\n\n args = requestBody;\n resCode = 201;\n break;\n\n case 'findFirst':\n case 'findUnique':\n case 'findMany':\n case 'aggregate':\n case 'groupBy':\n case 'count':\n if (method !== 'GET') {\n return this.makeBadInputErrorResponse('invalid request method, only GET is supported');\n }\n try {\n args = query?.['q']\n ? this.unmarshalQ(query['q'] as string, query['meta'] as string | undefined)\n : {};\n } catch {\n return this.makeBadInputErrorResponse('invalid \"q\" query parameter');\n }\n break;\n\n case 'update':\n case 'updateMany':\n case 'updateManyAndReturn':\n if (method !== 'PUT' && method !== 'PATCH') {\n return this.makeBadInputErrorResponse('invalid request method, only PUT or PATCH are supported');\n }\n if (!requestBody) {\n return this.makeBadInputErrorResponse('missing request body');\n }\n\n args = requestBody;\n break;\n\n case 'delete':\n case 'deleteMany':\n if (method !== 'DELETE') {\n return this.makeBadInputErrorResponse('invalid request method, only DELETE is supported');\n }\n try {\n args = query?.['q']\n ? this.unmarshalQ(query['q'] as string, query['meta'] as string | undefined)\n : {};\n } catch (err) {\n return this.makeBadInputErrorResponse(\n err instanceof Error ? err.message : 'invalid \"q\" query parameter',\n );\n }\n break;\n\n default:\n return this.makeBadInputErrorResponse('invalid operation: ' + op);\n }\n\n const { result: processedArgs, error } = await this.processRequestPayload(args);\n if (error) {\n return this.makeBadInputErrorResponse(error);\n }\n\n try {\n if (!this.isValidModel(client, model)) {\n return this.makeBadInputErrorResponse(`unknown model name: ${model}`);\n }\n\n log(\n this.options.log,\n 'debug',\n () => `handling \"${model}.${op}\" request with args: ${safeJSONStringify(processedArgs)}`,\n );\n\n const clientResult = await (client as any)[model][op](processedArgs);\n let responseBody: any = { data: clientResult };\n\n // superjson serialize response\n if (clientResult) {\n const { json, meta } = SuperJSON.serialize(clientResult);\n responseBody = { data: json };\n if (meta) {\n responseBody.meta = { serialization: meta };\n }\n }\n\n const response = { status: resCode, body: responseBody };\n log(\n this.options.log,\n 'debug',\n () => `sending response for \"${model}.${op}\" request: ${safeJSONStringify(response)}`,\n );\n return response;\n } catch (err) {\n log(this.options.log, 'error', `error occurred when handling \"${model}.${op}\" request`, err);\n if (err instanceof ZenStackError) {\n return this.makeZenStackErrorResponse(err);\n } else {\n return this.makeGenericErrorResponse(err);\n }\n }\n }\n\n private isValidModel(client: ClientContract<Schema>, model: string) {\n return Object.keys(client.$schema.models).some((m) => lowerCaseFirst(m) === lowerCaseFirst(model));\n }\n\n private makeBadInputErrorResponse(message: string) {\n const resp = {\n status: 400,\n body: { error: { message } },\n };\n log(this.options.log, 'debug', () => `sending error response: ${safeJSONStringify(resp)}`);\n return resp;\n }\n\n private makeGenericErrorResponse(err: unknown) {\n const resp = {\n status: 500,\n body: { error: { message: (err as Error).message || 'unknown error' } },\n };\n log(this.options.log, 'debug', () => `sending error response: ${safeJSONStringify(resp)}`);\n return resp;\n }\n\n private makeZenStackErrorResponse(err: ZenStackError) {\n let status = 400;\n const error: any = { message: err.message };\n if (err.cause && err.cause instanceof Error) {\n error.cause = err.cause.message;\n }\n\n if (err instanceof NotFoundError) {\n status = 404;\n error.model = err.model;\n } else if (err instanceof InputValidationError) {\n status = 422;\n error.rejectedByValidation = true;\n error.model = err.model;\n } else if (err instanceof RejectedByPolicyError) {\n status = 403;\n error.rejectedByPolicy = true;\n error.rejectReason = err.reason;\n error.model = err.model;\n }\n\n const resp = { status, body: { error } };\n log(this.options.log, 'debug', () => `sending error response: ${safeJSONStringify(resp)}`);\n return resp;\n }\n\n private async processRequestPayload(args: any) {\n const { meta, ...rest } = args;\n if (meta?.serialization) {\n try {\n // superjson deserialization\n args = SuperJSON.deserialize({ json: rest, meta: meta.serialization });\n } catch (err) {\n return { result: undefined, error: `failed to deserialize request payload: ${(err as Error).message}` };\n }\n }\n return { result: args, error: undefined };\n }\n\n private unmarshalQ(value: string, meta: string | undefined) {\n let parsedValue: any;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n throw new Error('invalid \"q\" query parameter');\n }\n\n if (meta) {\n let parsedMeta: any;\n try {\n parsedMeta = JSON.parse(meta);\n } catch {\n throw new Error('invalid \"meta\" query parameter');\n }\n\n if (parsedMeta.serialization) {\n return SuperJSON.deserialize({ json: parsedValue, meta: parsedMeta.serialization });\n }\n }\n\n return parsedValue;\n }\n}\n","import { Decimal } from 'decimal.js';\nimport SuperJSON from 'superjson';\nimport { match } from 'ts-pattern';\nimport type { LogConfig, LogLevel } from '../types';\n\nexport function log(logger: LogConfig | undefined, level: LogLevel, message: string | (() => string), error?: unknown) {\n if (!logger) {\n return;\n }\n\n const getMessage = typeof message === 'function' ? message : () => message;\n\n if (typeof logger === 'function') {\n logger(level, getMessage(), error);\n } else if (logger.includes(level)) {\n const logFn = match(level)\n .with('debug', () => console.debug)\n .with('info', () => console.info)\n .with('warn', () => console.warn)\n .with('error', () => console.error)\n .exhaustive();\n logFn(`@zenstackhq/server: [${level}] ${getMessage()}${error ? `\\n${error}` : ''}`);\n }\n}\n\n/**\n * Registers custom superjson serializers.\n */\nexport function registerCustomSerializers() {\n SuperJSON.registerCustom<Decimal, string>(\n {\n isApplicable: (v): v is Decimal => Decimal.isDecimal(v),\n serialize: (v) => v.toJSON(),\n deserialize: (v) => new Decimal(v),\n },\n 'Decimal',\n );\n\n // `Buffer` is not available in edge runtime\n if (globalThis.Buffer) {\n SuperJSON.registerCustom<Buffer, string>(\n {\n isApplicable: (v): v is Buffer => Buffer.isBuffer(v),\n serialize: (v) => v.toString('base64'),\n deserialize: (v) => Buffer.from(v, 'base64'),\n },\n 'Bytes',\n );\n }\n}\n"],"mappings":"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","names":["lowerCaseFirst","safeJSONStringify","InputValidationError","NotFoundError","RejectedByPolicyError","ZenStackError","SuperJSON","Decimal","SuperJSON","match","log","logger","level","message","error","getMessage","includes","logFn","match","with","console","debug","info","warn","exhaustive","registerCustomSerializers","SuperJSON","registerCustom","isApplicable","v","Decimal","isDecimal","serialize","toJSON","deserialize","globalThis","Buffer","isBuffer","toString","from","registerCustomSerializers","RPCApiHandler","options","schema","handleRequest","client","method","path","query","requestBody","parts","split","filter","p","op","pop","model","length","makeBadInputErrorResponse","lowerCaseFirst","toUpperCase","args","resCode","unmarshalQ","err","Error","message","result","processedArgs","error","processRequestPayload","isValidModel","log","safeJSONStringify","clientResult","responseBody","data","json","meta","SuperJSON","serialize","serialization","response","status","body","ZenStackError","makeZenStackErrorResponse","makeGenericErrorResponse","Object","keys","$schema","models","some","m","resp","cause","NotFoundError","InputValidationError","rejectedByValidation","RejectedByPolicyError","rejectedByPolicy","rejectReason","reason","rest","deserialize","undefined","value","parsedValue","JSON","parse","parsedMeta"]}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/express/index.ts
22
+ var express_exports = {};
23
+ __export(express_exports, {
24
+ ZenStackMiddleware: () => factory
25
+ });
26
+ module.exports = __toCommonJS(express_exports);
27
+
28
+ // src/express/middleware.ts
29
+ var factory = /* @__PURE__ */ __name((options) => {
30
+ const requestHandler = options.apiHandler;
31
+ return async (request, response, next) => {
32
+ const client = await options.getClient(request, response);
33
+ const { sendResponse } = options;
34
+ if (sendResponse === false && !client) {
35
+ throw new Error("unable to get ZenStackClient from request context");
36
+ }
37
+ if (!client) {
38
+ return response.status(500).json({
39
+ message: "unable to get ZenStackClient from request context"
40
+ });
41
+ }
42
+ const url = request.protocol + "://" + request.get("host") + request.originalUrl;
43
+ const searchParams = new URL(url).searchParams;
44
+ const query = Object.fromEntries(searchParams);
45
+ try {
46
+ const r = await requestHandler.handleRequest({
47
+ method: request.method,
48
+ path: request.path,
49
+ query,
50
+ requestBody: request.body,
51
+ client
52
+ });
53
+ if (sendResponse === false) {
54
+ response.locals["zenstack"] = {
55
+ status: r.status,
56
+ body: r.body
57
+ };
58
+ return next();
59
+ }
60
+ return response.status(r.status).json(r.body);
61
+ } catch (err) {
62
+ if (sendResponse === false) {
63
+ throw err;
64
+ }
65
+ return response.status(500).json({
66
+ message: `An unhandled error occurred: ${err}`
67
+ });
68
+ }
69
+ };
70
+ }, "factory");
71
+ // Annotate the CommonJS export names for ESM import in node:
72
+ 0 && (module.exports = {
73
+ ZenStackMiddleware
74
+ });
75
+ //# sourceMappingURL=express.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/express/index.ts","../src/express/middleware.ts"],"sourcesContent":["export { ZenStackMiddleware, type MiddlewareOptions } from './middleware';\n","import type { ClientContract } from '@zenstackhq/runtime';\nimport type { SchemaDef } from '@zenstackhq/runtime/schema';\nimport type { Handler, Request, Response } from 'express';\nimport type { ApiHandler } from '../types';\n\n/**\n * Express middleware options\n */\nexport interface MiddlewareOptions<Schema extends SchemaDef> {\n apiHandler: ApiHandler<Schema>;\n\n /**\n * Callback for getting a ZenStackClient for the given request\n */\n getClient: (req: Request, res: Response) => ClientContract<Schema> | Promise<ClientContract<Schema>>;\n\n /**\n * Controls if the middleware directly sends a response. If set to false,\n * the response is stored in the `res.locals` object and then the middleware\n * calls the `next()` function to pass the control to the next middleware.\n * Subsequent middleware or request handlers need to make sure to send\n * a response.\n *\n * Defaults to true;\n */\n sendResponse?: boolean;\n}\n\n/**\n * Creates an Express middleware for handling CRUD requests.\n */\nconst factory = <Schema extends SchemaDef>(options: MiddlewareOptions<Schema>): Handler => {\n const requestHandler = options.apiHandler;\n\n return async (request, response, next) => {\n const client = await options.getClient(request, response);\n const { sendResponse } = options;\n\n if (sendResponse === false && !client) {\n throw new Error('unable to get ZenStackClient from request context');\n }\n\n if (!client) {\n return response.status(500).json({ message: 'unable to get ZenStackClient from request context' });\n }\n\n // express converts query parameters with square brackets into object\n // e.g.: filter[foo]=bar is parsed to { filter: { foo: 'bar' } }\n // we need to revert this behavior and reconstruct params from original URL\n const url = request.protocol + '://' + request.get('host') + request.originalUrl;\n const searchParams = new URL(url).searchParams;\n const query = Object.fromEntries(searchParams);\n\n try {\n const r = await requestHandler.handleRequest({\n method: request.method,\n path: request.path,\n query,\n requestBody: request.body,\n client,\n });\n if (sendResponse === false) {\n // attach response and pass control to the next middleware\n response.locals['zenstack'] = {\n status: r.status,\n body: r.body,\n };\n return next();\n }\n return response.status(r.status).json(r.body);\n } catch (err) {\n if (sendResponse === false) {\n throw err;\n }\n return response.status(500).json({ message: `An unhandled error occurred: ${err}` });\n }\n };\n};\n\nexport default factory;\n\nexport { factory as ZenStackMiddleware };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AC+BA,IAAMA,UAAU,wBAA2BC,YAAAA;AACvC,QAAMC,iBAAiBD,QAAQE;AAE/B,SAAO,OAAOC,SAASC,UAAUC,SAAAA;AAC7B,UAAMC,SAAS,MAAMN,QAAQO,UAAUJ,SAASC,QAAAA;AAChD,UAAM,EAAEI,aAAY,IAAKR;AAEzB,QAAIQ,iBAAiB,SAAS,CAACF,QAAQ;AACnC,YAAM,IAAIG,MAAM,mDAAA;IACpB;AAEA,QAAI,CAACH,QAAQ;AACT,aAAOF,SAASM,OAAO,GAAA,EAAKC,KAAK;QAAEC,SAAS;MAAoD,CAAA;IACpG;AAKA,UAAMC,MAAMV,QAAQW,WAAW,QAAQX,QAAQY,IAAI,MAAA,IAAUZ,QAAQa;AACrE,UAAMC,eAAe,IAAIC,IAAIL,GAAAA,EAAKI;AAClC,UAAME,QAAQC,OAAOC,YAAYJ,YAAAA;AAEjC,QAAI;AACA,YAAMK,IAAI,MAAMrB,eAAesB,cAAc;QACzCC,QAAQrB,QAAQqB;QAChBC,MAAMtB,QAAQsB;QACdN;QACAO,aAAavB,QAAQwB;QACrBrB;MACJ,CAAA;AACA,UAAIE,iBAAiB,OAAO;AAExBJ,iBAASwB,OAAO,UAAA,IAAc;UAC1BlB,QAAQY,EAAEZ;UACViB,MAAML,EAAEK;QACZ;AACA,eAAOtB,KAAAA;MACX;AACA,aAAOD,SAASM,OAAOY,EAAEZ,MAAM,EAAEC,KAAKW,EAAEK,IAAI;IAChD,SAASE,KAAK;AACV,UAAIrB,iBAAiB,OAAO;AACxB,cAAMqB;MACV;AACA,aAAOzB,SAASM,OAAO,GAAA,EAAKC,KAAK;QAAEC,SAAS,gCAAgCiB,GAAAA;MAAM,CAAA;IACtF;EACJ;AACJ,GA9CgB;","names":["factory","options","requestHandler","apiHandler","request","response","next","client","getClient","sendResponse","Error","status","json","message","url","protocol","get","originalUrl","searchParams","URL","query","Object","fromEntries","r","handleRequest","method","path","requestBody","body","locals","err"]}
@@ -0,0 +1,31 @@
1
+ import { ClientContract } from '@zenstackhq/runtime';
2
+ import { SchemaDef } from '@zenstackhq/runtime/schema';
3
+ import { Request, Response, Handler } from 'express';
4
+ import { A as ApiHandler } from './types-BH-88xJo.cjs';
5
+
6
+ /**
7
+ * Express middleware options
8
+ */
9
+ interface MiddlewareOptions<Schema extends SchemaDef> {
10
+ apiHandler: ApiHandler<Schema>;
11
+ /**
12
+ * Callback for getting a ZenStackClient for the given request
13
+ */
14
+ getClient: (req: Request, res: Response) => ClientContract<Schema> | Promise<ClientContract<Schema>>;
15
+ /**
16
+ * Controls if the middleware directly sends a response. If set to false,
17
+ * the response is stored in the `res.locals` object and then the middleware
18
+ * calls the `next()` function to pass the control to the next middleware.
19
+ * Subsequent middleware or request handlers need to make sure to send
20
+ * a response.
21
+ *
22
+ * Defaults to true;
23
+ */
24
+ sendResponse?: boolean;
25
+ }
26
+ /**
27
+ * Creates an Express middleware for handling CRUD requests.
28
+ */
29
+ declare const factory: <Schema extends SchemaDef>(options: MiddlewareOptions<Schema>) => Handler;
30
+
31
+ export { type MiddlewareOptions, factory as ZenStackMiddleware };
@@ -0,0 +1,31 @@
1
+ import { ClientContract } from '@zenstackhq/runtime';
2
+ import { SchemaDef } from '@zenstackhq/runtime/schema';
3
+ import { Request, Response, Handler } from 'express';
4
+ import { A as ApiHandler } from './types-BH-88xJo.js';
5
+
6
+ /**
7
+ * Express middleware options
8
+ */
9
+ interface MiddlewareOptions<Schema extends SchemaDef> {
10
+ apiHandler: ApiHandler<Schema>;
11
+ /**
12
+ * Callback for getting a ZenStackClient for the given request
13
+ */
14
+ getClient: (req: Request, res: Response) => ClientContract<Schema> | Promise<ClientContract<Schema>>;
15
+ /**
16
+ * Controls if the middleware directly sends a response. If set to false,
17
+ * the response is stored in the `res.locals` object and then the middleware
18
+ * calls the `next()` function to pass the control to the next middleware.
19
+ * Subsequent middleware or request handlers need to make sure to send
20
+ * a response.
21
+ *
22
+ * Defaults to true;
23
+ */
24
+ sendResponse?: boolean;
25
+ }
26
+ /**
27
+ * Creates an Express middleware for handling CRUD requests.
28
+ */
29
+ declare const factory: <Schema extends SchemaDef>(options: MiddlewareOptions<Schema>) => Handler;
30
+
31
+ export { type MiddlewareOptions, factory as ZenStackMiddleware };
@@ -0,0 +1,50 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/express/middleware.ts
5
+ var factory = /* @__PURE__ */ __name((options) => {
6
+ const requestHandler = options.apiHandler;
7
+ return async (request, response, next) => {
8
+ const client = await options.getClient(request, response);
9
+ const { sendResponse } = options;
10
+ if (sendResponse === false && !client) {
11
+ throw new Error("unable to get ZenStackClient from request context");
12
+ }
13
+ if (!client) {
14
+ return response.status(500).json({
15
+ message: "unable to get ZenStackClient from request context"
16
+ });
17
+ }
18
+ const url = request.protocol + "://" + request.get("host") + request.originalUrl;
19
+ const searchParams = new URL(url).searchParams;
20
+ const query = Object.fromEntries(searchParams);
21
+ try {
22
+ const r = await requestHandler.handleRequest({
23
+ method: request.method,
24
+ path: request.path,
25
+ query,
26
+ requestBody: request.body,
27
+ client
28
+ });
29
+ if (sendResponse === false) {
30
+ response.locals["zenstack"] = {
31
+ status: r.status,
32
+ body: r.body
33
+ };
34
+ return next();
35
+ }
36
+ return response.status(r.status).json(r.body);
37
+ } catch (err) {
38
+ if (sendResponse === false) {
39
+ throw err;
40
+ }
41
+ return response.status(500).json({
42
+ message: `An unhandled error occurred: ${err}`
43
+ });
44
+ }
45
+ };
46
+ }, "factory");
47
+ export {
48
+ factory as ZenStackMiddleware
49
+ };
50
+ //# sourceMappingURL=express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/express/middleware.ts"],"sourcesContent":["import type { ClientContract } from '@zenstackhq/runtime';\nimport type { SchemaDef } from '@zenstackhq/runtime/schema';\nimport type { Handler, Request, Response } from 'express';\nimport type { ApiHandler } from '../types';\n\n/**\n * Express middleware options\n */\nexport interface MiddlewareOptions<Schema extends SchemaDef> {\n apiHandler: ApiHandler<Schema>;\n\n /**\n * Callback for getting a ZenStackClient for the given request\n */\n getClient: (req: Request, res: Response) => ClientContract<Schema> | Promise<ClientContract<Schema>>;\n\n /**\n * Controls if the middleware directly sends a response. If set to false,\n * the response is stored in the `res.locals` object and then the middleware\n * calls the `next()` function to pass the control to the next middleware.\n * Subsequent middleware or request handlers need to make sure to send\n * a response.\n *\n * Defaults to true;\n */\n sendResponse?: boolean;\n}\n\n/**\n * Creates an Express middleware for handling CRUD requests.\n */\nconst factory = <Schema extends SchemaDef>(options: MiddlewareOptions<Schema>): Handler => {\n const requestHandler = options.apiHandler;\n\n return async (request, response, next) => {\n const client = await options.getClient(request, response);\n const { sendResponse } = options;\n\n if (sendResponse === false && !client) {\n throw new Error('unable to get ZenStackClient from request context');\n }\n\n if (!client) {\n return response.status(500).json({ message: 'unable to get ZenStackClient from request context' });\n }\n\n // express converts query parameters with square brackets into object\n // e.g.: filter[foo]=bar is parsed to { filter: { foo: 'bar' } }\n // we need to revert this behavior and reconstruct params from original URL\n const url = request.protocol + '://' + request.get('host') + request.originalUrl;\n const searchParams = new URL(url).searchParams;\n const query = Object.fromEntries(searchParams);\n\n try {\n const r = await requestHandler.handleRequest({\n method: request.method,\n path: request.path,\n query,\n requestBody: request.body,\n client,\n });\n if (sendResponse === false) {\n // attach response and pass control to the next middleware\n response.locals['zenstack'] = {\n status: r.status,\n body: r.body,\n };\n return next();\n }\n return response.status(r.status).json(r.body);\n } catch (err) {\n if (sendResponse === false) {\n throw err;\n }\n return response.status(500).json({ message: `An unhandled error occurred: ${err}` });\n }\n };\n};\n\nexport default factory;\n\nexport { factory as ZenStackMiddleware };\n"],"mappings":";;;;AA+BA,IAAMA,UAAU,wBAA2BC,YAAAA;AACvC,QAAMC,iBAAiBD,QAAQE;AAE/B,SAAO,OAAOC,SAASC,UAAUC,SAAAA;AAC7B,UAAMC,SAAS,MAAMN,QAAQO,UAAUJ,SAASC,QAAAA;AAChD,UAAM,EAAEI,aAAY,IAAKR;AAEzB,QAAIQ,iBAAiB,SAAS,CAACF,QAAQ;AACnC,YAAM,IAAIG,MAAM,mDAAA;IACpB;AAEA,QAAI,CAACH,QAAQ;AACT,aAAOF,SAASM,OAAO,GAAA,EAAKC,KAAK;QAAEC,SAAS;MAAoD,CAAA;IACpG;AAKA,UAAMC,MAAMV,QAAQW,WAAW,QAAQX,QAAQY,IAAI,MAAA,IAAUZ,QAAQa;AACrE,UAAMC,eAAe,IAAIC,IAAIL,GAAAA,EAAKI;AAClC,UAAME,QAAQC,OAAOC,YAAYJ,YAAAA;AAEjC,QAAI;AACA,YAAMK,IAAI,MAAMrB,eAAesB,cAAc;QACzCC,QAAQrB,QAAQqB;QAChBC,MAAMtB,QAAQsB;QACdN;QACAO,aAAavB,QAAQwB;QACrBrB;MACJ,CAAA;AACA,UAAIE,iBAAiB,OAAO;AAExBJ,iBAASwB,OAAO,UAAA,IAAc;UAC1BlB,QAAQY,EAAEZ;UACViB,MAAML,EAAEK;QACZ;AACA,eAAOtB,KAAAA;MACX;AACA,aAAOD,SAASM,OAAOY,EAAEZ,MAAM,EAAEC,KAAKW,EAAEK,IAAI;IAChD,SAASE,KAAK;AACV,UAAIrB,iBAAiB,OAAO;AACxB,cAAMqB;MACV;AACA,aAAOzB,SAASM,OAAO,GAAA,EAAKC,KAAK;QAAEC,SAAS,gCAAgCiB,GAAAA;MAAM,CAAA;IACtF;EACJ;AACJ,GA9CgB;","names":["factory","options","requestHandler","apiHandler","request","response","next","client","getClient","sendResponse","Error","status","json","message","url","protocol","get","originalUrl","searchParams","URL","query","Object","fromEntries","r","handleRequest","method","path","requestBody","body","locals","err"]}
@@ -0,0 +1,68 @@
1
+ import { ClientContract } from '@zenstackhq/runtime';
2
+ import { SchemaDef } from '@zenstackhq/runtime/schema';
3
+
4
+ /**
5
+ * Log levels
6
+ */
7
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
8
+ /**
9
+ * Logger function
10
+ */
11
+ type Logger = (level: LogLevel, message: string, error?: unknown) => void;
12
+ /**
13
+ * Log configuration
14
+ */
15
+ type LogConfig = ReadonlyArray<LogLevel> | Logger;
16
+ /**
17
+ * API request context
18
+ */
19
+ type RequestContext<Schema extends SchemaDef> = {
20
+ /**
21
+ * The ZenStackClient instance
22
+ */
23
+ client: ClientContract<Schema>;
24
+ /**
25
+ * The HTTP method
26
+ */
27
+ method: string;
28
+ /**
29
+ * The request endpoint path (excluding any prefix)
30
+ */
31
+ path: string;
32
+ /**
33
+ * The query parameters
34
+ */
35
+ query?: Record<string, string | string[]>;
36
+ /**
37
+ * The request body object
38
+ */
39
+ requestBody?: unknown;
40
+ };
41
+ /**
42
+ * API response
43
+ */
44
+ type Response = {
45
+ /**
46
+ * HTTP status code
47
+ */
48
+ status: number;
49
+ /**
50
+ * Response body
51
+ */
52
+ body: unknown;
53
+ };
54
+ /**
55
+ * Framework-agnostic API handler.
56
+ */
57
+ interface ApiHandler<Schema extends SchemaDef> {
58
+ /**
59
+ * The schema associated with this handler.
60
+ */
61
+ get schema(): Schema;
62
+ /**
63
+ * Handle an API request.
64
+ */
65
+ handleRequest(context: RequestContext<Schema>): Promise<Response>;
66
+ }
67
+
68
+ export type { ApiHandler as A, LogConfig as L, RequestContext as R, Response as a };
@@ -0,0 +1,68 @@
1
+ import { ClientContract } from '@zenstackhq/runtime';
2
+ import { SchemaDef } from '@zenstackhq/runtime/schema';
3
+
4
+ /**
5
+ * Log levels
6
+ */
7
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
8
+ /**
9
+ * Logger function
10
+ */
11
+ type Logger = (level: LogLevel, message: string, error?: unknown) => void;
12
+ /**
13
+ * Log configuration
14
+ */
15
+ type LogConfig = ReadonlyArray<LogLevel> | Logger;
16
+ /**
17
+ * API request context
18
+ */
19
+ type RequestContext<Schema extends SchemaDef> = {
20
+ /**
21
+ * The ZenStackClient instance
22
+ */
23
+ client: ClientContract<Schema>;
24
+ /**
25
+ * The HTTP method
26
+ */
27
+ method: string;
28
+ /**
29
+ * The request endpoint path (excluding any prefix)
30
+ */
31
+ path: string;
32
+ /**
33
+ * The query parameters
34
+ */
35
+ query?: Record<string, string | string[]>;
36
+ /**
37
+ * The request body object
38
+ */
39
+ requestBody?: unknown;
40
+ };
41
+ /**
42
+ * API response
43
+ */
44
+ type Response = {
45
+ /**
46
+ * HTTP status code
47
+ */
48
+ status: number;
49
+ /**
50
+ * Response body
51
+ */
52
+ body: unknown;
53
+ };
54
+ /**
55
+ * Framework-agnostic API handler.
56
+ */
57
+ interface ApiHandler<Schema extends SchemaDef> {
58
+ /**
59
+ * The schema associated with this handler.
60
+ */
61
+ get schema(): Schema;
62
+ /**
63
+ * Handle an API request.
64
+ */
65
+ handleRequest(context: RequestContext<Schema>): Promise<Response>;
66
+ }
67
+
68
+ export type { ApiHandler as A, LogConfig as L, RequestContext as R, Response as a };
package/package.json CHANGED
@@ -1,13 +1,8 @@
1
1
  {
2
2
  "name": "@zenstackhq/server",
3
- "version": "2.21.0",
4
- "displayName": "ZenStack Server-side Adapters",
5
- "description": "ZenStack server-side adapters",
6
- "homepage": "https://zenstack.dev",
7
- "publishConfig": {
8
- "directory": "dist",
9
- "linkDirectory": true
10
- },
3
+ "version": "3.0.0-beta.13",
4
+ "description": "ZenStack automatic CRUD API handlers and server adapters",
5
+ "type": "module",
11
6
  "keywords": [
12
7
  "fastify",
13
8
  "express",
@@ -19,62 +14,66 @@
19
14
  ],
20
15
  "author": "ZenStack Team",
21
16
  "license": "MIT",
22
- "dependencies": {
23
- "superjson": "^1.13.0",
24
- "ts-japi": "^1.10.1",
25
- "url-pattern": "^1.0.3",
26
- "decimal.js": "^10.4.2",
27
- "@zenstackhq/runtime": "2.21.0"
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "exports": {
21
+ "./package.json": {
22
+ "import": "./package.json",
23
+ "require": "./package.json"
24
+ },
25
+ "./api": {
26
+ "import": {
27
+ "types": "./dist/api.d.ts",
28
+ "default": "./dist/api.js"
29
+ },
30
+ "require": {
31
+ "types": "./dist/api.d.cts",
32
+ "default": "./dist/api.cjs"
33
+ }
34
+ },
35
+ "./express": {
36
+ "import": {
37
+ "types": "./dist/express.d.ts",
38
+ "default": "./dist/express.js"
39
+ },
40
+ "require": {
41
+ "types": "./dist/express.d.cts",
42
+ "default": "./dist/express.cjs"
43
+ }
44
+ }
28
45
  },
29
- "peerDependencies": {
30
- "zod": "^3.25.0 || ^4.0.0"
46
+ "dependencies": {
47
+ "decimal.js": "^10.4.3",
48
+ "superjson": "^2.2.3",
49
+ "ts-pattern": "^5.7.1",
50
+ "@zenstackhq/common-helpers": "3.0.0-beta.13",
51
+ "@zenstackhq/runtime": "3.0.0-beta.13"
31
52
  },
32
53
  "devDependencies": {
33
- "@nestjs/common": "^10.3.7",
34
- "@nestjs/platform-express": "^10.3.7",
35
- "@nestjs/testing": "^10.3.7",
36
- "@sveltejs/kit": "1.21.0",
37
- "@types/body-parser": "^1.19.2",
38
- "@types/express": "^4.17.17",
39
- "@types/supertest": "^2.0.12",
40
- "body-parser": "^1.20.2",
41
- "elysia": "^1.3.1",
42
- "express": "^4.19.2",
43
- "fastify": "^4.14.1",
44
- "fastify-plugin": "^4.5.0",
45
- "h3": "^1.8.2",
46
- "hono": "^4.6.3",
47
- "isomorphic-fetch": "^3.0.0",
48
- "next": "14.2.4",
49
- "nuxt": "^3.7.4",
50
- "reflect-metadata": "^0.2.2",
51
- "supertest": "^6.3.3",
52
- "zod": "^3.25.0",
53
- "@zenstackhq/testtools": "2.21.0"
54
+ "@types/body-parser": "^1.19.6",
55
+ "@types/express": "^5.0.0",
56
+ "@types/supertest": "^6.0.3",
57
+ "body-parser": "^2.2.0",
58
+ "supertest": "^7.1.4",
59
+ "@zenstackhq/testtools": "3.0.0-beta.13",
60
+ "@zenstackhq/typescript-config": "3.0.0-beta.13",
61
+ "@zenstackhq/eslint-config": "3.0.0-beta.13",
62
+ "@zenstackhq/vitest-config": "3.0.0-beta.13"
54
63
  },
55
- "exports": {
56
- "./package.json": "./package.json",
57
- "./api": "./api/index.js",
58
- "./api/rest": "./api/rest/index.js",
59
- "./api/rpc": "./api/rpc/index.js",
60
- "./express": "./express/index.js",
61
- "./fastify": "./fastify/index.js",
62
- "./next/app-route-handler": "./next/app-route-handler.js",
63
- "./next": "./next/index.js",
64
- "./next/pages-route-handler": "./next/pages-route-handler.js",
65
- "./sveltekit": "./sveltekit/index.js",
66
- "./nuxt": "./nuxt/index.js",
67
- "./nestjs": "./nestjs/index.js",
68
- "./hono": "./hono/index.js",
69
- "./elysia": "./elysia/index.js",
70
- "./tanstack-start": "./tanstack-start/index.js",
71
- "./types": "./types.js"
64
+ "peerDependencies": {
65
+ "express": "^5.0.0"
66
+ },
67
+ "peerDependenciesMeta": {
68
+ "express": {
69
+ "optional": true
70
+ }
72
71
  },
73
72
  "scripts": {
74
- "clean": "rimraf dist",
75
- "build": "pnpm lint --max-warnings=0 && pnpm clean && tsc && copyfiles ./package.json ./README.md ./LICENSE dist && pnpm pack dist --pack-destination ../../../.build",
76
- "watch": "tsc --watch",
73
+ "build": "tsc --noEmit && tsup-node",
74
+ "watch": "tsup-node --watch",
77
75
  "lint": "eslint src --ext ts",
78
- "test": "jest"
76
+ "test": "vitest run",
77
+ "pack": "pnpm pack"
79
78
  }
80
79
  }
package/README.md DELETED
@@ -1,5 +0,0 @@
1
- # ZenStack Server Adapters
2
-
3
- This package provides adapters and utilities for integrating with popular Node.js servers, including Express, Fastify, and Nest.js.
4
-
5
- Visit [Homepage](https://zenstack.dev) for more details.
package/api/base.d.ts DELETED
@@ -1,49 +0,0 @@
1
- import type { DbClientContract, ModelMeta, ZodSchemas } from '@zenstackhq/runtime';
2
- import type { LoggerConfig } from '../types';
3
- /**
4
- * API request context
5
- */
6
- export type RequestContext = {
7
- /**
8
- * The PrismaClient instance
9
- */
10
- prisma: DbClientContract;
11
- /**
12
- * The HTTP method
13
- */
14
- method: string;
15
- /**
16
- * The request endpoint path (excluding any prefix)
17
- */
18
- path: string;
19
- /**
20
- * The query parameters
21
- */
22
- query?: Record<string, string | string[]>;
23
- /**
24
- * The request body object
25
- */
26
- requestBody?: unknown;
27
- /**
28
- * Model metadata. By default loaded from the @see loadPath path. You can pass
29
- * it in explicitly to override.
30
- */
31
- modelMeta?: ModelMeta;
32
- /**
33
- * Zod schemas for validating create and update payloads. By default loaded from
34
- * the @see loadPath path. You can pass it in explicitly to override.
35
- */
36
- zodSchemas?: ZodSchemas;
37
- /**
38
- * Logging configuration. Set to `null` to disable logging.
39
- * If unset or set to `undefined`, log will be output to console.
40
- */
41
- logger?: LoggerConfig;
42
- };
43
- /**
44
- * Base class for API handlers
45
- */
46
- export declare abstract class APIHandlerBase {
47
- protected readonly defaultModelMeta: ModelMeta | undefined;
48
- constructor();
49
- }
package/api/base.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.APIHandlerBase = void 0;
4
- const shared_1 = require("../shared");
5
- /**
6
- * Base class for API handlers
7
- */
8
- class APIHandlerBase {
9
- constructor() {
10
- try {
11
- this.defaultModelMeta = (0, shared_1.getDefaultModelMeta)();
12
- }
13
- catch {
14
- // noop
15
- }
16
- }
17
- }
18
- exports.APIHandlerBase = APIHandlerBase;
19
- //# sourceMappingURL=base.js.map
package/api/base.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/api/base.ts"],"names":[],"mappings":";;;AACA,sCAAgD;AAmDhD;;GAEG;AACH,MAAsB,cAAc;IAIhC;QACI,IAAI,CAAC;YACD,IAAI,CAAC,gBAAgB,GAAG,IAAA,4BAAmB,GAAE,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO;QACX,CAAC;IACL,CAAC;CACJ;AAXD,wCAWC"}
package/api/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export { RPCApiHandler } from './rpc';
2
- export { RestApiHandler } from './rest';
package/api/index.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RestApiHandler = exports.RPCApiHandler = void 0;
4
- var rpc_1 = require("./rpc");
5
- Object.defineProperty(exports, "RPCApiHandler", { enumerable: true, get: function () { return rpc_1.RPCApiHandler; } });
6
- var rest_1 = require("./rest");
7
- Object.defineProperty(exports, "RestApiHandler", { enumerable: true, get: function () { return rest_1.RestApiHandler; } });
8
- //# sourceMappingURL=index.js.map
package/api/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":";;;AAAA,6BAAsC;AAA7B,oGAAA,aAAa,OAAA;AACtB,+BAAwC;AAA/B,sGAAA,cAAc,OAAA"}