@raiyyan/brisk 0.1.0 → 0.2.0

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 (174) hide show
  1. package/AGENTS.md +135 -67
  2. package/README.md +467 -139
  3. package/dist/src/cli/agents.js +5 -5
  4. package/dist/src/cli/agents.js.map +1 -1
  5. package/dist/src/cli/cli.d.ts +1 -1
  6. package/dist/src/cli/cli.d.ts.map +1 -1
  7. package/dist/src/cli/cli.js +22 -36
  8. package/dist/src/cli/cli.js.map +1 -1
  9. package/dist/src/cli/init.d.ts +8 -11
  10. package/dist/src/cli/init.d.ts.map +1 -1
  11. package/dist/src/cli/init.js +120 -96
  12. package/dist/src/cli/init.js.map +1 -1
  13. package/dist/src/cli/render.d.ts +30 -0
  14. package/dist/src/cli/render.d.ts.map +1 -0
  15. package/dist/src/cli/render.js +101 -0
  16. package/dist/src/cli/render.js.map +1 -0
  17. package/dist/src/cli/system.d.ts +2 -2
  18. package/dist/src/cli/system.d.ts.map +1 -1
  19. package/dist/src/cli/system.js +3 -5
  20. package/dist/src/cli/system.js.map +1 -1
  21. package/dist/src/client/client.d.ts.map +1 -1
  22. package/dist/src/client/client.js +32 -5
  23. package/dist/src/client/client.js.map +1 -1
  24. package/dist/src/client/index.d.ts +1 -1
  25. package/dist/src/client/index.d.ts.map +1 -1
  26. package/dist/src/di/container.d.ts +10 -2
  27. package/dist/src/di/container.d.ts.map +1 -1
  28. package/dist/src/di/container.js +20 -3
  29. package/dist/src/di/container.js.map +1 -1
  30. package/dist/src/http/app.d.ts +41 -12
  31. package/dist/src/http/app.d.ts.map +1 -1
  32. package/dist/src/http/app.js.map +1 -1
  33. package/dist/src/http/context.d.ts +5 -5
  34. package/dist/src/http/context.js +5 -5
  35. package/dist/src/http/controller.d.ts +26 -9
  36. package/dist/src/http/controller.d.ts.map +1 -1
  37. package/dist/src/http/controller.js +25 -52
  38. package/dist/src/http/controller.js.map +1 -1
  39. package/dist/src/http/error-handler.d.ts +27 -0
  40. package/dist/src/http/error-handler.d.ts.map +1 -1
  41. package/dist/src/http/error-handler.js +26 -3
  42. package/dist/src/http/error-handler.js.map +1 -1
  43. package/dist/src/http/instance.d.ts +2 -2
  44. package/dist/src/http/instance.d.ts.map +1 -1
  45. package/dist/src/http/instance.js +107 -39
  46. package/dist/src/http/instance.js.map +1 -1
  47. package/dist/src/http/middleware.d.ts +104 -17
  48. package/dist/src/http/middleware.d.ts.map +1 -1
  49. package/dist/src/http/middleware.js +85 -26
  50. package/dist/src/http/middleware.js.map +1 -1
  51. package/dist/src/http/openapi.d.ts.map +1 -1
  52. package/dist/src/http/openapi.js +30 -2
  53. package/dist/src/http/openapi.js.map +1 -1
  54. package/dist/src/http/routes.d.ts +29 -7
  55. package/dist/src/http/routes.d.ts.map +1 -1
  56. package/dist/src/http/validation.d.ts +16 -0
  57. package/dist/src/http/validation.d.ts.map +1 -0
  58. package/dist/src/http/validation.js +51 -0
  59. package/dist/src/http/validation.js.map +1 -0
  60. package/dist/src/index.d.ts +2 -2
  61. package/dist/src/index.d.ts.map +1 -1
  62. package/dist/src/index.js +2 -2
  63. package/dist/src/index.js.map +1 -1
  64. package/dist/src/testing/test-client.d.ts +8 -6
  65. package/dist/src/testing/test-client.d.ts.map +1 -1
  66. package/dist/src/testing/test-client.js +3 -2
  67. package/dist/src/testing/test-client.js.map +1 -1
  68. package/package.json +3 -2
  69. package/starters/minimal/.env.example +3 -0
  70. package/starters/minimal/.oxfmtrc.json +5 -0
  71. package/starters/minimal/.oxlintrc.json +14 -0
  72. package/starters/minimal/AGENTS.md +23 -0
  73. package/starters/minimal/CLAUDE.md +2 -0
  74. package/starters/minimal/README.md +53 -0
  75. package/starters/minimal/_gitignore +3 -0
  76. package/starters/minimal/package.json +29 -0
  77. package/starters/minimal/src/app.ts +14 -0
  78. package/starters/minimal/src/env.ts +7 -0
  79. package/starters/minimal/src/features/index.ts +8 -0
  80. package/starters/minimal/src/features/notes/notes.controller.ts +38 -0
  81. package/starters/minimal/src/features/notes/notes.repository.ts +36 -0
  82. package/starters/minimal/src/features/notes/notes.schema.ts +24 -0
  83. package/starters/minimal/src/features/notes/notes.service.ts +33 -0
  84. package/starters/minimal/src/main.ts +4 -0
  85. package/starters/minimal/src/schemas.ts +26 -0
  86. package/starters/minimal/templates/feature/src/features/index.ts.controllers.insert +1 -0
  87. package/starters/minimal/templates/feature/src/features/index.ts.imports.insert +1 -0
  88. package/starters/minimal/templates/feature/src/features/{{kebab}}/{{kebab}}.controller.ts +38 -0
  89. package/starters/minimal/templates/feature/src/features/{{kebab}}/{{kebab}}.repository.ts +36 -0
  90. package/starters/minimal/templates/feature/src/features/{{kebab}}/{{kebab}}.schema.ts +24 -0
  91. package/starters/minimal/templates/feature/src/features/{{kebab}}/{{kebab}}.service.ts +33 -0
  92. package/starters/minimal/templates/feature/test/{{kebab}}.service.test.ts +20 -0
  93. package/starters/minimal/templates/feature/test/{{kebab}}.test.ts +35 -0
  94. package/starters/minimal/templates/middleware/src/middlewares/{{kebab}}.ts +12 -0
  95. package/starters/minimal/test/notes.service.test.ts +20 -0
  96. package/starters/minimal/test/notes.test.ts +35 -0
  97. package/starters/minimal/tsconfig.json +17 -0
  98. package/starters/minimal/vitest.config.ts +9 -0
  99. package/starters/sqlite-auth/.dockerignore +8 -0
  100. package/starters/sqlite-auth/.env.example +9 -0
  101. package/starters/sqlite-auth/.oxfmtrc.json +5 -0
  102. package/starters/sqlite-auth/.oxlintrc.json +14 -0
  103. package/starters/sqlite-auth/AGENTS.md +23 -0
  104. package/starters/sqlite-auth/CLAUDE.md +2 -0
  105. package/starters/sqlite-auth/Dockerfile +23 -0
  106. package/starters/sqlite-auth/README.md +93 -0
  107. package/starters/sqlite-auth/_gitignore +5 -0
  108. package/starters/sqlite-auth/compose.yaml +14 -0
  109. package/starters/sqlite-auth/package.json +35 -0
  110. package/starters/sqlite-auth/public/.gitkeep +0 -0
  111. package/starters/sqlite-auth/src/app.ts +39 -0
  112. package/starters/sqlite-auth/src/auth/tokens.ts +41 -0
  113. package/starters/sqlite-auth/src/database/clock.ts +4 -0
  114. package/starters/sqlite-auth/src/database/database.ts +29 -0
  115. package/starters/sqlite-auth/src/database/errors.ts +11 -0
  116. package/starters/sqlite-auth/src/database/migrations.ts +29 -0
  117. package/starters/sqlite-auth/src/env.ts +17 -0
  118. package/starters/sqlite-auth/src/features/auth/auth.controller.ts +28 -0
  119. package/starters/sqlite-auth/src/features/index.ts +12 -0
  120. package/starters/sqlite-auth/src/features/notes/notes.controller.ts +39 -0
  121. package/starters/sqlite-auth/src/features/notes/notes.repository.ts +47 -0
  122. package/starters/sqlite-auth/src/features/notes/notes.schema.ts +24 -0
  123. package/starters/sqlite-auth/src/features/notes/notes.service.ts +33 -0
  124. package/starters/sqlite-auth/src/features/users/admin-seed.ts +21 -0
  125. package/starters/sqlite-auth/src/features/users/users.controller.ts +42 -0
  126. package/starters/sqlite-auth/src/features/users/users.errors.ts +13 -0
  127. package/starters/sqlite-auth/src/features/users/users.repository.ts +77 -0
  128. package/starters/sqlite-auth/src/features/users/users.schema.ts +35 -0
  129. package/starters/sqlite-auth/src/features/users/users.service.ts +80 -0
  130. package/starters/sqlite-auth/src/main.ts +4 -0
  131. package/starters/sqlite-auth/src/middlewares/authenticate.ts +29 -0
  132. package/starters/sqlite-auth/src/schemas.ts +26 -0
  133. package/starters/sqlite-auth/templates/feature/src/database/migrations.ts.migrations.insert +5 -0
  134. package/starters/sqlite-auth/templates/feature/src/features/index.ts.controllers.insert +1 -0
  135. package/starters/sqlite-auth/templates/feature/src/features/index.ts.imports.insert +1 -0
  136. package/starters/sqlite-auth/templates/feature/src/features/{{kebab}}/{{kebab}}.controller.ts +39 -0
  137. package/starters/sqlite-auth/templates/feature/src/features/{{kebab}}/{{kebab}}.repository.ts +47 -0
  138. package/starters/sqlite-auth/templates/feature/src/features/{{kebab}}/{{kebab}}.schema.ts +24 -0
  139. package/starters/sqlite-auth/templates/feature/src/features/{{kebab}}/{{kebab}}.service.ts +33 -0
  140. package/starters/sqlite-auth/templates/feature/test/{{kebab}}.service.test.ts +20 -0
  141. package/starters/sqlite-auth/templates/feature/test/{{kebab}}.test.ts +41 -0
  142. package/starters/sqlite-auth/templates/middleware/src/middlewares/{{kebab}}.ts +12 -0
  143. package/starters/sqlite-auth/test/auth.test.ts +18 -0
  144. package/starters/sqlite-auth/test/helpers.ts +13 -0
  145. package/starters/sqlite-auth/test/notes.service.test.ts +20 -0
  146. package/starters/sqlite-auth/test/notes.test.ts +41 -0
  147. package/starters/sqlite-auth/test/users.service.test.ts +25 -0
  148. package/starters/sqlite-auth/test/users.test.ts +164 -0
  149. package/starters/sqlite-auth/tsconfig.json +17 -0
  150. package/starters/sqlite-auth/vitest.config.ts +15 -0
  151. package/dist/src/cli/generate.d.ts +0 -9
  152. package/dist/src/cli/generate.d.ts.map +0 -1
  153. package/dist/src/cli/generate.js +0 -39
  154. package/dist/src/cli/generate.js.map +0 -1
  155. package/dist/src/cli/templates/auth.d.ts +0 -4
  156. package/dist/src/cli/templates/auth.d.ts.map +0 -1
  157. package/dist/src/cli/templates/auth.js +0 -90
  158. package/dist/src/cli/templates/auth.js.map +0 -1
  159. package/dist/src/cli/templates/database.d.ts +0 -4
  160. package/dist/src/cli/templates/database.d.ts.map +0 -1
  161. package/dist/src/cli/templates/database.js +0 -107
  162. package/dist/src/cli/templates/database.js.map +0 -1
  163. package/dist/src/cli/templates/docker.d.ts +0 -4
  164. package/dist/src/cli/templates/docker.d.ts.map +0 -1
  165. package/dist/src/cli/templates/docker.js +0 -102
  166. package/dist/src/cli/templates/docker.js.map +0 -1
  167. package/dist/src/cli/templates/feature.d.ts +0 -8
  168. package/dist/src/cli/templates/feature.d.ts.map +0 -1
  169. package/dist/src/cli/templates/feature.js +0 -145
  170. package/dist/src/cli/templates/feature.js.map +0 -1
  171. package/dist/src/cli/templates/project.d.ts +0 -24
  172. package/dist/src/cli/templates/project.d.ts.map +0 -1
  173. package/dist/src/cli/templates/project.js +0 -166
  174. package/dist/src/cli/templates/project.js.map +0 -1
@@ -23,7 +23,9 @@ const ERROR_RESPONSE = {
23
23
  */
24
24
  export function buildOpenApi(endpoints, options) {
25
25
  const paths = {};
26
+ const securitySchemes = {};
26
27
  for (const endpoint of endpoints) {
28
+ Object.assign(securitySchemes, endpoint.security);
27
29
  for (const path of openApiPaths(endpoint.path)) {
28
30
  const item = (paths[path] ??= {});
29
31
  item[endpoint.method] = operation(endpoint, path);
@@ -38,7 +40,10 @@ export function buildOpenApi(endpoints, options) {
38
40
  },
39
41
  ...(options.servers ? { servers: options.servers } : {}),
40
42
  paths,
41
- components: { schemas: { ErrorResponse: ERROR_RESPONSE } },
43
+ components: {
44
+ schemas: { ErrorResponse: ERROR_RESPONSE },
45
+ ...(Object.keys(securitySchemes).length > 0 ? { securitySchemes } : {}),
46
+ },
42
47
  };
43
48
  }
44
49
  function operation(endpoint, path) {
@@ -64,6 +69,9 @@ function operation(endpoint, path) {
64
69
  return {
65
70
  tags: [endpoint.tag],
66
71
  operationId: endpoint.name === undefined ? undefined : `${endpoint.tag}.${endpoint.name}`,
72
+ ...(endpoint.security
73
+ ? { security: [Object.fromEntries(Object.keys(endpoint.security).map((name) => [name, []]))] }
74
+ : {}),
67
75
  ...(parameters.length > 0 ? { parameters } : {}),
68
76
  ...(schemas.body
69
77
  ? {
@@ -111,7 +119,27 @@ function fieldParameters(schema, location) {
111
119
  }
112
120
  function jsonSchema(schema, io) {
113
121
  const { $schema: _dialect, ...json } = z.toJSONSchema(schema, { io, unrepresentable: "any" });
114
- return json;
122
+ return withoutFormatPatterns(json);
123
+ }
124
+ /**
125
+ * Removes `pattern` wherever `format` already names the type (`email`, `uuid`, `date-time`). Zod emits both,
126
+ * and docs UIs such as Swagger UI build example values from the regex: several KB of noise for an email.
127
+ */
128
+ function withoutFormatPatterns(json) {
129
+ const result = {};
130
+ for (const [key, value] of Object.entries(json)) {
131
+ if (key === "pattern" && typeof json["format"] === "string")
132
+ continue;
133
+ result[key] = clean(value);
134
+ }
135
+ return result;
136
+ }
137
+ function clean(value) {
138
+ if (Array.isArray(value))
139
+ return value.map(clean);
140
+ if (typeof value !== "object" || value === null)
141
+ return value;
142
+ return withoutFormatPatterns({ ...value });
115
143
  }
116
144
  function objectProperties(json) {
117
145
  const properties = json["properties"];
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../../src/http/openapi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../../src/http/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuBxB,MAAM,cAAc,GAAe;IACjC,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC;YAC1C,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;gBACjD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC3B,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC9B;SACF;KACF;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAwC,EAAE,OAAuB;IAC5F,MAAM,KAAK,GAA+B,EAAE,CAAC;IAC7C,MAAM,eAAe,GAA4B,EAAE,CAAC;IACpD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;SACnF;QACD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,KAAK;QACL,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE;YAC1C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE;KACF,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,QAA4B,EAAE,IAAY;IAC3D,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IAC7B,MAAM,UAAU,GAAG;QACjB,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC;QACvC,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;QAC1C,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;KAC9C,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,MAAM,SAAS,GAAe;QAC5B,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ;YACzB,CAAC,CAAC;gBACE,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC;gBAC9B,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE;aACpF;YACH,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE;QACtC,OAAO,EAAE;YACP,WAAW,EAAE,OAAO;YACpB,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,EAAE,EAAE;SAC5F;KACF,CAAC;IACF,OAAO;QACL,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;QACpB,WAAW,EAAE,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE;QACzF,GAAG,CAAC,QAAQ,CAAC,QAAQ;YACnB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YAC9F,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,OAAO,CAAC,IAAI;YACd,CAAC,CAAC;gBACE,WAAW,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE;iBAC/E;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;QAClC,OAAO,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,MAA6B;IACjE,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACjE,IAAI;QACJ,EAAE,EAAE,MAAM;QACV,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/C,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,eAAe,CAAC,MAA6B,EAAE,QAA4B;IAClF,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,IAAI;QACJ,EAAE,EAAE,QAAQ;QACZ,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAC5B,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CAAC,MAAiB,EAAE,EAAsB;IAC3D,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAAC,IAAgB;IAC7C,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ;YAAE,SAAS;QACtE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,OAAO,qBAAqB,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAgB;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,SAAS,QAAQ,CAAC,MAAc;IAC9B,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,SAAS,CAAC;AACnD,CAAC"}
@@ -43,12 +43,16 @@ type Field<K extends string, T> = [keyof T] extends [never] ? {} : {} extends T
43
43
  type SchemaInput<S, Fallback> = S extends z.ZodType ? z.input<S> : Fallback;
44
44
  /** A value a URL can carry. */
45
45
  type UrlValue = string | number | boolean;
46
+ /** A value the client can write into a URL: it turns numbers, booleans, bigints and dates into text. */
47
+ type UrlScalar = UrlValue | bigint | Date;
48
+ type SchemaOutput<S, Fallback> = S extends z.ZodType ? z.output<S> : Fallback;
46
49
  /**
47
- * Path and query fields as a client writes them. A coercing schema (`z.coerce.number()`) accepts `unknown`;
48
- * here it accepts what a URL can carry instead.
50
+ * Path and query fields as a client writes them: the schema's input, or its output when that is something a
51
+ * URL can carry, so \`z.stringbool()\` takes \`true\` and \`z.coerce.number()\` takes \`2\`. A coercing schema's
52
+ * \`unknown\` input accepts any URL value.
49
53
  */
50
- type UrlFields<T> = {
51
- [K in keyof T]: unknown extends T[K] ? UrlValue | UrlValue[] : T[K];
54
+ type UrlFields<In, Out> = {
55
+ [K in keyof In]: unknown extends In[K] ? UrlValue | UrlValue[] : In[K] | (K extends keyof Out ? Extract<Out[K], UrlScalar | readonly UrlScalar[] | undefined> : never);
52
56
  };
53
57
  /**
54
58
  * Headers a client sends: the typed ones from the route's schema, plus any others, such as the
@@ -58,7 +62,7 @@ type HeadersField<H> = H extends z.ZodType ? Field<"headers", z.input<H> & Recor
58
62
  headers?: Record<string, string>;
59
63
  };
60
64
  /** What a client sends: path params, query, body and headers, each typed by its schema. */
61
- export type RouteInput<Path extends string, P, Q, B, H> = Field<"params", UrlFields<SchemaInput<P, PathParams<Path>>>> & Field<"query", UrlFields<SchemaInput<Q, {}>>> & Field<"body", SchemaInput<B, {}>> & HeadersField<H>;
65
+ export type RouteInput<Path extends string, P, Q, B, H> = Field<"params", UrlFields<SchemaInput<P, PathParams<Path>>, SchemaOutput<P, {}>>> & Field<"query", UrlFields<SchemaInput<Q, {}>, SchemaOutput<Q, {}>>> & Field<"body", SchemaInput<B, {}>> & HeadersField<H>;
62
66
  /** A Node stream, recognized by shape so these types never need `@types/node`. */
63
67
  interface StreamLike {
64
68
  pipe(...args: never[]): unknown;
@@ -113,7 +117,25 @@ type RoutesOf<C> = {
113
117
  export type Client<T> = {
114
118
  readonly [K in keyof T]: T[K] extends Route<infer I, infer O> ? Call<I, O> : Client<T[K]>;
115
119
  };
116
- /** One route as a function. `init` passes fetch options such as `signal` or extra headers. */
117
- export type Call<I, O> = {} extends I ? (input?: I, init?: RequestInit) => Promise<O> : (input: I, init?: RequestInit) => Promise<O>;
120
+ /** A body sent as it is, without JSON encoding: a file, a form, bytes or a stream. */
121
+ export type RawBody = FormData | Blob | URLSearchParams | ArrayBuffer | ArrayBufferView | ReadableStream | string;
122
+ /** The input of {@link Call.raw}: the route's own input, with any body `fetch` accepts. */
123
+ type RawInput<I> = Omit<I, "body"> & {
124
+ body?: RawBody | (I extends {
125
+ body?: infer B;
126
+ } ? B : never);
127
+ };
128
+ type Send<I, R> = {} extends I ? (input?: I, init?: RequestInit) => Promise<R> : (input: I, init?: RequestInit) => Promise<R>;
129
+ /**
130
+ * One route as a function. It resolves to the route's output and rejects with `ApiError` on a non-2xx
131
+ * response; `init` passes fetch options such as `signal`.
132
+ */
133
+ export type Call<I, O> = Send<I, O> & {
134
+ /**
135
+ * The same request, resolving to the raw `Response` whatever its status: for downloads, uploads
136
+ * (`body: formData`) and anything that is not JSON. The client's headers are still applied.
137
+ */
138
+ readonly raw: Send<RawInput<I>, Response>;
139
+ };
118
140
  export {};
119
141
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/http/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/http/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,WAAW,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO;IACtD,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,0EAA0E;AAC1E,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC;CAC7E;AAED,mGAAmG;AACnG,KAAK,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACvD,EAAE,GACF,EAAE,SAAS,CAAC,GACV;KAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;CAAE,GAChB;KAAG,CAAC,IAAI,CAAC,GAAG,CAAC;CAAE,CAAC;AAEtB,KAAK,WAAW,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAE5E,+BAA+B;AAC/B,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,wGAAwG;AACxG,KAAK,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;AAE1C,KAAK,YAAY,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAE9E;;;;GAIG;AACH,KAAK,SAAS,CAAC,EAAE,EAAE,GAAG,IAAI;KACvB,CAAC,IAAI,MAAM,EAAE,GAAG,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,GAClC,QAAQ,GAAG,QAAQ,EAAE,GACrB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC;CAC1G,CAAC;AAEF;;;GAGG;AACH,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GACtC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACrD;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEzC,2FAA2F;AAC3F,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,CAC7D,QAAQ,EACR,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACjE,GACC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAClE,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GACjC,YAAY,CAAC,CAAC,CAAC,CAAC;AAElB,kFAAkF;AAClF,UAAU,UAAU;IAClB,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,MAAM,IAAI,MAAM,CAAC,CAAA;CAAE,GACpD,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GACxC,CAAC,GACD,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC5B,OAAO,CAAC,CAAC,CAAC,EAAE,GACZ,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAC3F,KAAK,CAAC;AAEhB;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GACtD,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GACX,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,GACnC,SAAS,GACT,QAAQ,SAAS,UAAU,GAAG,UAAU,GACtC,QAAQ,GACR,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE1B,yFAAyF;AACzF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,cAAc,SAAS,MAAM,CAAC,GACjD,CAAC,SAAS;IAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GAC7C,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GACxB,KAAK,GACP,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEhB,yFAAyF;AACzF,KAAK,QAAQ,CAAC,CAAC,IAAI;KAChB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,CAAC,GACrG,CAAC,GACD,KAAK;CACV,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IACtB,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1F,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,OAAO,GACf,QAAQ,GACR,IAAI,GACJ,eAAe,GACf,WAAW,GACX,eAAe,GACf,cAAc,GACd,MAAM,CAAC;AAEX,2FAA2F;AAC3F,KAAK,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,SAAS;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;CAAE,CAAC;AAErG,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,GAC1B,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7C,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACpC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;CAC3C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Zod parsing shared by routes and middlewares. Every parse is synchronous, the fast path, unless a schema has
4
+ * async refinements: then it switches to `safeParseAsync` and the value comes back wrapped in {@link Pending}.
5
+ */
6
+ /** An input whose schema needs async validation; never a value a schema can produce. */
7
+ export declare class Pending {
8
+ readonly promise: Promise<unknown>;
9
+ constructor(promise: Promise<unknown>);
10
+ }
11
+ export declare const settle: (value: unknown) => unknown;
12
+ export declare function parseInput(schema: z.ZodType | undefined, value: unknown, location: string): unknown;
13
+ /** A result that breaks its own response schema is a server bug: a 500, never a 400. */
14
+ export declare function serializeOutput(schema: z.ZodType | undefined, value: unknown): unknown;
15
+ export declare function safeParse(schema: z.ZodType, value: unknown): z.ZodSafeParseResult<unknown> | Promise<z.ZodSafeParseResult<unknown>>;
16
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/http/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AAEH,wFAAwF;AACxF,qBAAa,OAAO;IAClB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,YAAY,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAEpC;CACF;AAED,eAAO,MAAM,MAAM,UAAW,OAAO,KAAG,OAA6D,CAAC;AAEtG,wBAAgB,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMnG;AAOD,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAItF;AAOD,wBAAgB,SAAS,CACvB,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,KAAK,EAAE,OAAO,GACb,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAOxE"}
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+ import { ValidationError } from "../errors/http-errors.js";
3
+ /**
4
+ * Zod parsing shared by routes and middlewares. Every parse is synchronous, the fast path, unless a schema has
5
+ * async refinements: then it switches to `safeParseAsync` and the value comes back wrapped in {@link Pending}.
6
+ */
7
+ /** An input whose schema needs async validation; never a value a schema can produce. */
8
+ export class Pending {
9
+ promise;
10
+ constructor(promise) {
11
+ this.promise = promise;
12
+ }
13
+ }
14
+ export const settle = (value) => (value instanceof Pending ? value.promise : value);
15
+ export function parseInput(schema, value, location) {
16
+ if (!schema)
17
+ return value;
18
+ const input = value ?? {};
19
+ const result = safeParse(schema, input);
20
+ if (result instanceof Promise)
21
+ return new Pending(result.then((settled) => unwrapInput(settled, location)));
22
+ return unwrapInput(result, location);
23
+ }
24
+ function unwrapInput(result, location) {
25
+ if (result.success)
26
+ return result.data;
27
+ throw ValidationError.fromZod(result.error, location);
28
+ }
29
+ /** A result that breaks its own response schema is a server bug: a 500, never a 400. */
30
+ export function serializeOutput(schema, value) {
31
+ if (!schema)
32
+ return value;
33
+ const result = safeParse(schema, value);
34
+ return result instanceof Promise ? result.then(unwrapOutput) : unwrapOutput(result);
35
+ }
36
+ function unwrapOutput(result) {
37
+ if (result.success)
38
+ return result.data;
39
+ throw new Error(`Response does not match its schema:\n${z.prettifyError(result.error)}`);
40
+ }
41
+ export function safeParse(schema, value) {
42
+ try {
43
+ return schema.safeParse(value);
44
+ }
45
+ catch (error) {
46
+ if (error instanceof z.core.$ZodAsyncError)
47
+ return schema.safeParseAsync(value);
48
+ throw error;
49
+ }
50
+ }
51
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/http/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;GAGG;AAEH,wFAAwF;AACxF,MAAM,OAAO,OAAO;IACT,OAAO,CAAmB;IACnC,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,CAAC,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAEtG,MAAM,UAAU,UAAU,CAAC,MAA6B,EAAE,KAAc,EAAE,QAAgB;IACxF,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,IAAI,MAAM,YAAY,OAAO;QAAE,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5G,OAAO,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,WAAW,CAAC,MAAqC,EAAE,QAAgB;IAC1E,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACvC,MAAM,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,eAAe,CAAC,MAA6B,EAAE,KAAc;IAC3E,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,YAAY,CAAC,MAAqC;IACzD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACvC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,MAAiB,EACjB,KAAc;IAEd,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAChF,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -14,9 +14,9 @@ export { defineController, type Controller, type ControllerOptions, type GroupOp
14
14
  export type { PathParams } from "./http/path-params.ts";
15
15
  export type { ApiOf, Client, HttpMethod, Jsonify, Manifest, Route, Routes } from "./http/routes.ts";
16
16
  export { defineEnv, type DefineEnvOptions } from "./config/env.ts";
17
- export { defaultErrorFormatter, type ErrorFormatter, type ErrorMapper } from "./http/error-handler.ts";
17
+ export { defaultErrorFormatter, ErrorTranslator, type ErrorFormatter, type ErrorMapper, } from "./http/error-handler.ts";
18
18
  export * from "./errors/index.ts";
19
19
  export { createLogger, Logger, type LoggerOptions } from "./config/logger.ts";
20
- export { defineMiddleware, type Middleware, type MiddlewareContext } from "./http/middleware.ts";
20
+ export { defineMiddleware, fromExpress, type Middleware, type MiddlewareContext, type MiddlewareInput, type MiddlewareOptions, type SecurityScheme, type SecuritySchemes, } from "./http/middleware.ts";
21
21
  export { z } from "zod";
22
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,SAAS,EACT,KAAK,GAAG,EACR,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,SAAS,EACT,WAAW,EACX,MAAM,EACN,UAAU,EACV,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,KAAK,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACvG,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,SAAS,EACT,KAAK,GAAG,EACR,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,SAAS,EACT,WAAW,EACX,MAAM,EACN,UAAU,EACV,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,KAAK,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,GACjB,MAAM,yBAAyB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
package/dist/src/index.js CHANGED
@@ -11,9 +11,9 @@ export { Container, defineToken, inject, injectLazy, provide, } from "./di/index
11
11
  export { getContext } from "./http/context.js";
12
12
  export { defineController, } from "./http/controller.js";
13
13
  export { defineEnv } from "./config/env.js";
14
- export { defaultErrorFormatter } from "./http/error-handler.js";
14
+ export { defaultErrorFormatter, ErrorTranslator, } from "./http/error-handler.js";
15
15
  export * from "./errors/index.js";
16
16
  export { createLogger, Logger } from "./config/logger.js";
17
- export { defineMiddleware } from "./http/middleware.js";
17
+ export { defineMiddleware, fromExpress, } from "./http/middleware.js";
18
18
  export { z } from "zod";
19
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,SAAS,GAWV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,SAAS,EACT,WAAW,EACX,MAAM,EACN,UAAU,EACV,OAAO,GAUR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,gBAAgB,GAOjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAyC,MAAM,yBAAyB,CAAC;AACvG,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAsB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAA2C,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,SAAS,GAWV,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,SAAS,EACT,WAAW,EACX,MAAM,EACN,UAAU,EACV,OAAO,GAUR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,gBAAgB,GAOjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,eAAe,GAGhB,MAAM,yBAAyB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAsB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EACL,gBAAgB,EAChB,WAAW,GAOZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { ErrorResponse } from "../errors/http-errors.ts";
2
- import type { App, AppInstance, ControllerMap, CreateOptions } from "../http/app.ts";
2
+ import type { App, AppInstance, CreateOptions } from "../http/app.ts";
3
3
  import type { ApiOf, Client } from "../http/routes.ts";
4
4
  /** A response from a {@link TestClient} raw request. */
5
5
  export interface TestResponse {
@@ -19,15 +19,16 @@ export interface TestRequest {
19
19
  }
20
20
  type Send = (path: string, request?: TestRequest) => Promise<TestResponse>;
21
21
  /**
22
- * A client for an instance started by {@link createTestClient}: the typed client as `call`, and raw requests
22
+ * A client for an instance started by {@link createTestClient}. Its type argument is the app:
23
+ * `TestClient<typeof app>`: the typed client as `call`, and raw requests
23
24
  * by path for checking status codes, headers and malformed input.
24
25
  */
25
- export interface TestClient<Api = {}> {
26
+ export interface TestClient<A = unknown> {
26
27
  readonly baseUrl: string;
27
28
  /** The running instance, for its `container` or `server`. */
28
29
  readonly instance: AppInstance;
29
30
  /** The typed client: `await api.call.users.get({ params: { id } })`. Rejects with `ApiError` on non-2xx. */
30
- readonly call: Client<Api>;
31
+ readonly call: Client<ApiOf<A>>;
31
32
  get: Send;
32
33
  post: Send;
33
34
  put: Send;
@@ -38,7 +39,8 @@ export interface TestClient<Api = {}> {
38
39
  }
39
40
  /**
40
41
  * Starts a fresh instance of the app on a random local port, with its full lifecycle, and returns a client for
41
- * it. `providers` replace the app's own, typically with fakes. `close()` shuts the instance down gracefully.
42
+ * it. `providers` are added after the app's own: a value for the same token wins, so fakes replace real
43
+ * services, and a class is created alongside the app's. `close()` shuts the instance down gracefully.
42
44
  *
43
45
  * @example
44
46
  * ```ts
@@ -51,7 +53,7 @@ export interface TestClient<Api = {}> {
51
53
  * await api.close();
52
54
  * ```
53
55
  */
54
- export declare function createTestClient<C extends ControllerMap>(app: App<C>, options?: CreateOptions): Promise<TestClient<ApiOf<App<C>>>>;
56
+ export declare function createTestClient<A extends App>(app: A, options?: CreateOptions): Promise<TestClient<A>>;
55
57
  /**
56
58
  * Reads the error out of a response, failing the test when the body is not an error response.
57
59
  *
@@ -1 +1 @@
1
- {"version":3,"file":"test-client.d.ts","sourceRoot":"","sources":["../../../src/testing/test-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,wGAAwG;IACxG,IAAI,EAAE,OAAO,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAKD,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3E;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,GAAG,GAAG,EAAE;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,4GAA4G;IAC5G,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,GAAG,EAAE,IAAI,CAAC;IACV,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,IAAI,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,EAAE,IAAI,CAAC;IACb,0CAA0C;IAC1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,aAAa,EAC5D,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EACX,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA0CpC;AAWD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAExE"}
1
+ {"version":3,"file":"test-client.d.ts","sourceRoot":"","sources":["../../../src/testing/test-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEvD,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,wGAAwG;IACxG,IAAI,EAAE,OAAO,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAKD,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,4GAA4G;IAC5G,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,GAAG,EAAE,IAAI,CAAC;IACV,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,IAAI,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,EAAE,IAAI,CAAC;IACb,0CAA0C;IAC1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,GAAG,EAClD,GAAG,EAAE,CAAC,EACN,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CA0CxB;AAWD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAExE"}
@@ -4,7 +4,8 @@ import { createClient } from "../client/client.js";
4
4
  const JSON_TYPE = /^application\/(?:[\w.-]+\+)?json\b/i;
5
5
  /**
6
6
  * Starts a fresh instance of the app on a random local port, with its full lifecycle, and returns a client for
7
- * it. `providers` replace the app's own, typically with fakes. `close()` shuts the instance down gracefully.
7
+ * it. `providers` are added after the app's own: a value for the same token wins, so fakes replace real
8
+ * services, and a class is created alongside the app's. `close()` shuts the instance down gracefully.
8
9
  *
9
10
  * @example
10
11
  * ```ts
@@ -46,7 +47,7 @@ export async function createTestClient(app, options = {}) {
46
47
  return {
47
48
  baseUrl,
48
49
  instance,
49
- call: createClient(instance, { baseUrl }),
50
+ call: createClient(instance.manifest, { baseUrl }),
50
51
  get: send("GET"),
51
52
  post: send("POST"),
52
53
  put: send("PUT"),
@@ -1 +1 @@
1
- {"version":3,"file":"test-client.js","sourceRoot":"","sources":["../../../src/testing/test-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-client.js","sourceRoot":"","sources":["../../../src/testing/test-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raiyyan/brisk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A small, typed, opinionated layer over Express 5 and Zod: validation, DI, lifecycle and errors without the boilerplate.",
5
5
  "keywords": [
6
6
  "api",
@@ -29,7 +29,8 @@
29
29
  "dist",
30
30
  "AGENTS.md",
31
31
  "README.md",
32
- "LICENSE"
32
+ "LICENSE",
33
+ "starters"
33
34
  ],
34
35
  "type": "module",
35
36
  "sideEffects": false,
@@ -0,0 +1,3 @@
1
+ NODE_ENV=development
2
+ PORT=3000
3
+ LOG_LEVEL=info
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "printWidth": 110,
4
+ "ignorePatterns": ["templates", "node_modules", "coverage"]
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["typescript", "import", "unicorn", "oxc", "vitest"],
4
+ "categories": {
5
+ "correctness": "error",
6
+ "suspicious": "warn"
7
+ },
8
+ "rules": {
9
+ "typescript/no-floating-promises": "error",
10
+ "typescript/no-misused-promises": "error",
11
+ "import/no-cycle": "error"
12
+ },
13
+ "ignorePatterns": ["templates", "node_modules", "coverage"]
14
+ }
@@ -0,0 +1,23 @@
1
+ # AGENTS.md
2
+
3
+ <!-- brisk:start -->
4
+
5
+ ## Building with brisk
6
+
7
+ This app uses [brisk](https://www.npmjs.com/package/@raiyyan/brisk), a typed layer over Express 5 and Zod.
8
+ Before writing or changing server code, read the full guide: `node_modules/@raiyyan/brisk/AGENTS.md`.
9
+
10
+ Essentials:
11
+
12
+ - The app is declared once in `src/app.ts` with `defineApp`; `app.listen(port)` runs it, `createTestClient(app, { providers })` tests it.
13
+ - Routes are named: a controller's setup returns `{ list: route.get(...), create: route.post(...) }`. The names form the typed client (`api.users.create({ body })`).
14
+ - Validate every input with a Zod schema on the route; set `response` to a DTO schema so internal fields never leak.
15
+ - New code follows this project's own templates: `npx brisk g feature <name>` renders `templates/feature/`. Edit the templates when the project's conventions change.
16
+ - Dependencies: `readonly #repo = inject(Repository)` in class fields. No decorators, no constructor wiring.
17
+ - Errors: `throw new NotFoundError("…")` (or another error class) anywhere. Never try/catch to build responses; never call `next()`.
18
+ - Shared request logic: `defineMiddleware` returning an object types `ctx`; declare `params` or `query` it reads to get them validated first. Express middleware such as multer goes in a route's `use` through `fromExpress()`.
19
+ - App-wide middleware goes in `defineApp({ use })` (`fromExpress(cors())` included); handlers that are not brisk routes (static files, GraphQL, webhooks) go in `defineApp({ mount })`. Express settings go in `http.settings`.
20
+ - Long-lived work (WebSockets, jobs, consumers, pools) is a provider class with `onInit`, `onReady`, `onDrain`, `onShutdown`; a feature lists its own in `defineController({ providers })`.
21
+ - Test with `createTestClient` from `@raiyyan/brisk/testing`: `api.call.<controller>.<route>(input)` is typed; `api.post(path)` checks raw HTTP.
22
+
23
+ <!-- brisk:end -->
@@ -0,0 +1,2 @@
1
+ @AGENTS.md
2
+ @node_modules/@raiyyan/brisk/AGENTS.md
@@ -0,0 +1,53 @@
1
+ # minimal
2
+
3
+ An API built with [brisk](https://github.com/MohammadRaiyyan/brisk) on Express 5 and Zod. It has no database: the example feature keeps its records in memory. Created with `npx brisk init` (the `minimal` starter).
4
+
5
+ ## Run it
6
+
7
+ ```bash
8
+ cp .env.example .env
9
+ npm run dev
10
+ ```
11
+
12
+ The API listens on port 3000 under `/api`. `GET /health` is the health check and `GET /openapi.json` the OpenAPI document.
13
+
14
+ | Script | What it does |
15
+ | ------------------------- | ------------------------------------------ |
16
+ | `dev` | Runs the server and restarts it on changes |
17
+ | `start` | Runs the server |
18
+ | `test` | Runs the tests (vitest) |
19
+ | `typecheck` | Checks types (`tsc --noEmit`) |
20
+ | `lint` | oxlint |
21
+ | `format` / `format:check` | oxfmt |
22
+ | `brisk g <kind> <name>` | Generates code from `templates/<kind>/` |
23
+
24
+ Node 24 or later runs the TypeScript sources directly; there is no build step.
25
+
26
+ ## Layout
27
+
28
+ | Path | What it holds |
29
+ | ---------------- | ------------------------------------------------------------------------------------------- |
30
+ | `src/env.ts` | Environment variables, validated at startup |
31
+ | `src/app.ts` | The app: controllers, logger, OpenAPI, error settings. `export type Api` for a typed client |
32
+ | `src/main.ts` | Starts the server |
33
+ | `src/schemas.ts` | Shared schema helpers: `isoDate()`, `PageQuery`, `page(item)` |
34
+ | `src/features/` | One folder per feature (schema, repository, service, controller), registered in `index.ts` |
35
+ | `templates/` | What `brisk g` renders: `feature` and `middleware`. Yours to edit |
36
+ | `test/` | HTTP tests with `createTestClient`, and service tests without HTTP |
37
+
38
+ ## Add a feature
39
+
40
+ ```bash
41
+ npx brisk g feature products
42
+ ```
43
+
44
+ This writes `src/features/products/`, its tests, and registers the controller in `src/features/index.ts` (keep the `@brisk:` marker lines there). The repository stores records in a `Map`; replace it with your database and the service does not change.
45
+
46
+ `npx brisk g middleware tenant` writes `src/middlewares/tenant.ts`. To change what new code looks like, edit the files in `templates/`; any folder you add there becomes a new `brisk g` kind.
47
+
48
+ The `notes` feature is an example generated from `templates/feature`. Delete `src/features/notes/`, `test/notes.test.ts`, `test/notes.service.test.ts` and its two lines in `src/features/index.ts` when you no longer need it.
49
+
50
+ ## Learn more
51
+
52
+ - [brisk documentation](https://github.com/MohammadRaiyyan/brisk#readme)
53
+ - `AGENTS.md` and `CLAUDE.md` point coding agents at the brisk guide (`npx brisk agents` refreshes them).
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ .env
3
+ coverage
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "starter-minimal",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "node --watch src/main.ts",
7
+ "start": "node src/main.ts",
8
+ "typecheck": "tsc --noEmit",
9
+ "test": "vitest run",
10
+ "brisk": "brisk",
11
+ "lint": "oxlint --type-aware",
12
+ "format": "oxfmt",
13
+ "format:check": "oxfmt --check"
14
+ },
15
+ "dependencies": {
16
+ "@raiyyan/brisk": "workspace:*"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^26.6.6",
20
+ "oxfmt": "^0.78.0",
21
+ "oxlint": "^1.93.0",
22
+ "oxlint-tsgolint": "^7.0.2007",
23
+ "typescript": "^7.0.2",
24
+ "vitest": "^5.1.0"
25
+ },
26
+ "engines": {
27
+ "node": ">=24"
28
+ }
29
+ }
@@ -0,0 +1,14 @@
1
+ import { createLogger, defineApp } from "@raiyyan/brisk";
2
+ import { env } from "./env.ts";
3
+ import { controllers } from "./features/index.ts";
4
+
5
+ export const app = defineApp({
6
+ prefix: "/api",
7
+ controllers,
8
+ logger: createLogger({ level: env.NODE_ENV === "test" ? "silent" : env.LOG_LEVEL }),
9
+ openapi: { title: "API", version: "0.1.0" },
10
+ errors: { exposeInternal: env.NODE_ENV === "development" },
11
+ });
12
+
13
+ /** The API's type, for a frontend's typed client: `createClient<Api>(manifest, { baseUrl })`. */
14
+ export type Api = typeof app;
@@ -0,0 +1,7 @@
1
+ import { defineEnv, z } from "@raiyyan/brisk";
2
+
3
+ export const env = defineEnv({
4
+ NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
5
+ PORT: z.coerce.number().int().positive().default(3000),
6
+ LOG_LEVEL: z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]).default("info"),
7
+ });
@@ -0,0 +1,8 @@
1
+ import { notesController } from "./notes/notes.controller.ts";
2
+ // @brisk:imports
3
+
4
+ /** Every controller by name. The names are the typed client's top level: `api.notes.get(...)`. */
5
+ export const controllers = {
6
+ notes: notesController,
7
+ // @brisk:controllers
8
+ };
@@ -0,0 +1,38 @@
1
+ import { defineController, inject } from "@raiyyan/brisk";
2
+ import { page } from "../../schemas.ts";
3
+ import {
4
+ CreateNoteBody,
5
+ NoteIdParams,
6
+ NoteResponse,
7
+ ListNotesQuery,
8
+ UpdateNoteBody,
9
+ } from "./notes.schema.ts";
10
+ import { NotesService } from "./notes.service.ts";
11
+
12
+ export const notesController = defineController({ prefix: "/notes" }, (route) => {
13
+ const notes = inject(NotesService);
14
+
15
+ return {
16
+ list: route.get("/", { query: ListNotesQuery, response: page(NoteResponse) }, ({ query }) =>
17
+ notes.list(query),
18
+ ),
19
+
20
+ get: route.get("/:id", { params: NoteIdParams, response: NoteResponse }, ({ params }) =>
21
+ notes.get(params.id),
22
+ ),
23
+
24
+ create: route.post("/", { body: CreateNoteBody, response: NoteResponse }, ({ body }) =>
25
+ notes.create(body),
26
+ ),
27
+
28
+ update: route.patch(
29
+ "/:id",
30
+ { params: NoteIdParams, body: UpdateNoteBody, response: NoteResponse },
31
+ ({ params, body }) => notes.update(params.id, body),
32
+ ),
33
+
34
+ remove: route.delete("/:id", { params: NoteIdParams }, async ({ params }) => {
35
+ await notes.remove(params.id);
36
+ }),
37
+ };
38
+ });