lumen-framework 3.1.1 → 4.0.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 (258) hide show
  1. package/README.md +75 -109
  2. package/bin/lumen +23 -41
  3. package/dist/cli.cjs +856 -479
  4. package/dist/cli.cjs.map +4 -4
  5. package/dist/index.js +3273 -1719
  6. package/dist/index.js.map +4 -4
  7. package/dist/index.mjs +3251 -1697
  8. package/dist/index.mjs.map +4 -4
  9. package/dist/testing.js +280 -0
  10. package/dist/testing.js.map +7 -0
  11. package/dist/testing.mjs +252 -0
  12. package/dist/testing.mjs.map +7 -0
  13. package/dist/types/errors/links-only-error.d.ts +13 -0
  14. package/dist/types/errors/reserved-field-name-error.d.ts +13 -0
  15. package/dist/types/errors/unknown-attribute-error.d.ts +13 -0
  16. package/dist/types/index.d.ts +14 -0
  17. package/dist/types/interfaces.d.ts +1 -1
  18. package/dist/types/packages/application/index.d.ts +38 -45
  19. package/dist/types/packages/application/initialize.d.ts +3 -5
  20. package/dist/types/packages/application/interfaces.d.ts +13 -5
  21. package/dist/types/packages/application/utils/create-controller.d.ts +14 -4
  22. package/dist/types/packages/application/utils/create-serializer.d.ts +2 -2
  23. package/dist/types/packages/application/utils/normalize-port.d.ts +1 -3
  24. package/dist/types/packages/application/utils/resolve-visibility.d.ts +15 -0
  25. package/dist/types/packages/application/utils/restrict-open-namespaces.d.ts +19 -0
  26. package/dist/types/packages/application/utils/validate-attributes.d.ts +17 -0
  27. package/dist/types/packages/application/utils/validate-links-only.d.ts +19 -0
  28. package/dist/types/packages/application/utils/validate-namespaced-serializers.d.ts +3 -3
  29. package/dist/types/packages/application/utils/validate-reserved-names.d.ts +12 -0
  30. package/dist/types/packages/application/utils/warn-query-param-names.d.ts +10 -0
  31. package/dist/types/packages/cli/commands/dbcreate.d.ts +1 -1
  32. package/dist/types/packages/cli/commands/dbdrop.d.ts +1 -1
  33. package/dist/types/packages/cli/commands/destroy.d.ts +3 -2
  34. package/dist/types/packages/cli/commands/generate.d.ts +5 -5
  35. package/dist/types/packages/cli/commands/index.d.ts +0 -1
  36. package/dist/types/packages/cli/generator/index.d.ts +6 -6
  37. package/dist/types/packages/cli/generator/interfaces.d.ts +3 -3
  38. package/dist/types/packages/cli/generator/utils/create-generator.d.ts +2 -2
  39. package/dist/types/packages/cli/generator/utils/generate-type.d.ts +9 -9
  40. package/dist/types/packages/cli/generator/utils/migration-conflict.d.ts +4 -4
  41. package/dist/types/packages/cli/templates/pnpm-workspace.d.ts +15 -0
  42. package/dist/types/packages/cli/utils/create-spinner.d.ts +14 -0
  43. package/dist/types/packages/cli/utils/print-statements.d.ts +12 -0
  44. package/dist/types/packages/cli/utils/server-database.d.ts +27 -0
  45. package/dist/types/packages/compiler/interfaces.d.ts +1 -1
  46. package/dist/types/packages/config/interfaces.d.ts +10 -4
  47. package/dist/types/packages/controller/constants.d.ts +7 -2
  48. package/dist/types/packages/controller/errors/related-record-not-found-error.d.ts +4 -4
  49. package/dist/types/packages/controller/index.d.ts +364 -473
  50. package/dist/types/packages/controller/interfaces.d.ts +21 -6
  51. package/dist/types/packages/controller/utils/find-many.d.ts +2 -5
  52. package/dist/types/packages/controller/utils/find-one.d.ts +2 -5
  53. package/dist/types/packages/controller/utils/params-to-query.d.ts +8 -10
  54. package/dist/types/packages/controller/utils/resolve-relationships.d.ts +1 -3
  55. package/dist/types/packages/controller/utils/validate-relationships.d.ts +5 -3
  56. package/dist/types/packages/controller/visibility/errors.d.ts +21 -0
  57. package/dist/types/packages/controller/visibility/index.d.ts +51 -0
  58. package/dist/types/packages/database/attribute/index.d.ts +4 -6
  59. package/dist/types/packages/database/attribute/interfaces.d.ts +1 -1
  60. package/dist/types/packages/database/attribute/utils/create-attribute.d.ts +3 -5
  61. package/dist/types/packages/database/attribute/utils/create-getter.d.ts +2 -2
  62. package/dist/types/packages/database/attribute/utils/create-setter.d.ts +3 -5
  63. package/dist/types/packages/database/constants.d.ts +1 -0
  64. package/dist/types/packages/database/errors/index.d.ts +1 -0
  65. package/dist/types/packages/database/errors/invalid-driver-error.d.ts +1 -3
  66. package/dist/types/packages/database/errors/migrations-pending-error.d.ts +1 -3
  67. package/dist/types/packages/database/errors/model-missing-error.d.ts +1 -3
  68. package/dist/types/packages/database/errors/relationship-config-error.d.ts +10 -0
  69. package/dist/types/packages/database/errors/unique-constraint-error.d.ts +1 -1
  70. package/dist/types/packages/database/index.d.ts +9 -6
  71. package/dist/types/packages/database/initialize.d.ts +3 -5
  72. package/dist/types/packages/database/interfaces.d.ts +115 -25
  73. package/dist/types/packages/database/migration/index.d.ts +5 -7
  74. package/dist/types/packages/database/migration/interfaces.d.ts +2 -4
  75. package/dist/types/packages/database/migration/utils/generate-timestamp.d.ts +9 -1
  76. package/dist/types/packages/database/model/index.d.ts +348 -759
  77. package/dist/types/packages/database/model/initialize-class.d.ts +7 -1
  78. package/dist/types/packages/database/model/interfaces.d.ts +30 -12
  79. package/dist/types/packages/database/model/utils/attribute.d.ts +14 -0
  80. package/dist/types/packages/database/model/utils/get-columns.d.ts +1 -3
  81. package/dist/types/packages/database/model/utils/persistence.d.ts +5 -14
  82. package/dist/types/packages/database/model/utils/process-write-error.d.ts +2 -2
  83. package/dist/types/packages/database/model/utils/run-hooks.d.ts +7 -3
  84. package/dist/types/packages/database/model/utils/validate.d.ts +4 -1
  85. package/dist/types/packages/database/query/errors/record-not-found-error.d.ts +1 -1
  86. package/dist/types/packages/database/query/index.d.ts +179 -3
  87. package/dist/types/packages/database/query/runner/index.d.ts +1 -3
  88. package/dist/types/packages/database/query/runner/utils/build-results.d.ts +3 -4
  89. package/dist/types/packages/database/query/utils/format-select.d.ts +1 -3
  90. package/dist/types/packages/database/relationship/index.d.ts +7 -6
  91. package/dist/types/packages/database/relationship/interfaces.d.ts +16 -3
  92. package/dist/types/packages/database/relationship/utils/getters.d.ts +7 -13
  93. package/dist/types/packages/database/relationship/utils/inverse-setters.d.ts +5 -9
  94. package/dist/types/packages/database/relationship/utils/setters.d.ts +7 -13
  95. package/dist/types/packages/database/relationship/utils/unassociate.d.ts +1 -3
  96. package/dist/types/packages/database/relationship/utils/update-relationship.d.ts +6 -2
  97. package/dist/types/packages/database/transaction/index.d.ts +9 -10
  98. package/dist/types/packages/database/transaction/interfaces.d.ts +7 -1
  99. package/dist/types/packages/database/utils/connect.d.ts +16 -3
  100. package/dist/types/packages/database/utils/create-migrations.d.ts +1 -3
  101. package/dist/types/packages/database/utils/normalize-model-name.d.ts +1 -3
  102. package/dist/types/packages/database/utils/pending-migrations.d.ts +1 -3
  103. package/dist/types/packages/database/utils/primary-key-type.d.ts +10 -0
  104. package/dist/types/packages/database/utils/type-for-column.d.ts +3 -5
  105. package/dist/types/packages/database/utils/validate-relationships.d.ts +13 -0
  106. package/dist/types/packages/database/validation/errors/validation-error.d.ts +4 -4
  107. package/dist/types/packages/database/validation/index.d.ts +3 -5
  108. package/dist/types/packages/database/validation/interfaces.d.ts +1 -1
  109. package/dist/types/packages/freezeable/map/index.d.ts +1 -3
  110. package/dist/types/packages/freezeable/set/index.d.ts +1 -3
  111. package/dist/types/packages/freezeable/utils/freeze.d.ts +5 -15
  112. package/dist/types/packages/freezeable/utils/is-frozen.d.ts +1 -3
  113. package/dist/types/packages/fs/index.d.ts +7 -7
  114. package/dist/types/packages/fs/interfaces.d.ts +4 -4
  115. package/dist/types/packages/fs/utils/parse-path.d.ts +2 -2
  116. package/dist/types/packages/fs/watcher/interfaces.d.ts +1 -1
  117. package/dist/types/packages/jsonapi/errors/invalid-content-type-error.d.ts +3 -5
  118. package/dist/types/packages/jsonapi/errors/not-acceptable-error.d.ts +2 -4
  119. package/dist/types/packages/jsonapi/errors/unsupported-media-type-error.d.ts +2 -4
  120. package/dist/types/packages/jsonapi/index.d.ts +1 -1
  121. package/dist/types/packages/jsonapi/interfaces.d.ts +47 -36
  122. package/dist/types/packages/jsonapi/utils/has-media-type-params.d.ts +1 -1
  123. package/dist/types/packages/jsonapi/utils/is-jsonapi.d.ts +1 -1
  124. package/dist/types/packages/jsonapi/utils/media-type.d.ts +2 -2
  125. package/dist/types/packages/loader/builder/index.d.ts +3 -3
  126. package/dist/types/packages/loader/builder/interfaces.d.ts +7 -7
  127. package/dist/types/packages/loader/builder/utils/create-children-builder.d.ts +2 -2
  128. package/dist/types/packages/loader/builder/utils/create-parent-builder.d.ts +9 -2
  129. package/dist/types/packages/loader/builder/utils/sort-by-namespace.d.ts +2 -2
  130. package/dist/types/packages/loader/index.d.ts +1 -1
  131. package/dist/types/packages/loader/interfaces.d.ts +2 -2
  132. package/dist/types/packages/loader/resolver/index.d.ts +2 -2
  133. package/dist/types/packages/loader/resolver/utils/closest-ancestor.d.ts +2 -2
  134. package/dist/types/packages/loader/resolver/utils/closest-child.d.ts +2 -2
  135. package/dist/types/packages/logger/constants.d.ts +3 -3
  136. package/dist/types/packages/logger/errors/invalid-config-error.d.ts +5 -0
  137. package/dist/types/packages/logger/index.d.ts +65 -142
  138. package/dist/types/packages/logger/interfaces.d.ts +52 -10
  139. package/dist/types/packages/logger/request-logger/index.d.ts +3 -5
  140. package/dist/types/packages/logger/request-logger/interfaces.d.ts +5 -5
  141. package/dist/types/packages/logger/request-logger/templates.d.ts +5 -9
  142. package/dist/types/packages/logger/request-logger/utils/filter-params.d.ts +6 -1
  143. package/dist/types/packages/logger/request-logger/utils/log-json.d.ts +2 -4
  144. package/dist/types/packages/logger/request-logger/utils/log-text.d.ts +1 -3
  145. package/dist/types/packages/logger/request-logger/utils/params-for.d.ts +9 -0
  146. package/dist/types/packages/logger/utils/error-name.d.ts +7 -0
  147. package/dist/types/packages/logger/utils/line.d.ts +1 -3
  148. package/dist/types/packages/logger/writer/constants.d.ts +0 -1
  149. package/dist/types/packages/logger/writer/index.d.ts +6 -6
  150. package/dist/types/packages/logger/writer/interfaces.d.ts +2 -2
  151. package/dist/types/packages/logger/writer/utils/format-message.d.ts +2 -2
  152. package/dist/types/packages/lumenify/index.d.ts +20 -5
  153. package/dist/types/packages/lumenify/utils/create-response-proxy.d.ts +1 -1
  154. package/dist/types/packages/pm/cluster/index.d.ts +56 -7
  155. package/dist/types/packages/pm/cluster/interfaces.d.ts +2 -1
  156. package/dist/types/packages/pm/index.d.ts +2 -2
  157. package/dist/types/packages/router/definitions/context/index.d.ts +5 -7
  158. package/dist/types/packages/router/definitions/context/utils/create-definition-group.d.ts +3 -5
  159. package/dist/types/packages/router/definitions/context/utils/create-definition.d.ts +11 -6
  160. package/dist/types/packages/router/definitions/context/utils/normalize-resource-args.d.ts +4 -5
  161. package/dist/types/packages/router/definitions/index.d.ts +5 -9
  162. package/dist/types/packages/router/definitions/interfaces.d.ts +4 -4
  163. package/dist/types/packages/router/index.d.ts +23 -11
  164. package/dist/types/packages/router/interfaces.d.ts +4 -4
  165. package/dist/types/packages/router/namespace/index.d.ts +7 -9
  166. package/dist/types/packages/router/namespace/interfaces.d.ts +3 -3
  167. package/dist/types/packages/router/namespace/utils/normalize-name.d.ts +1 -3
  168. package/dist/types/packages/router/namespace/utils/normalize-path.d.ts +1 -3
  169. package/dist/types/packages/router/resource/index.d.ts +7 -8
  170. package/dist/types/packages/router/resource/interfaces.d.ts +12 -4
  171. package/dist/types/packages/router/resource/utils/normalize-only.d.ts +3 -5
  172. package/dist/types/packages/router/route/action/enhancers/resource.d.ts +1 -3
  173. package/dist/types/packages/router/route/action/enhancers/track-perf.d.ts +1 -3
  174. package/dist/types/packages/router/route/action/index.d.ts +7 -2
  175. package/dist/types/packages/router/route/action/interfaces.d.ts +4 -0
  176. package/dist/types/packages/router/route/action/utils/create-page-links.d.ts +21 -5
  177. package/dist/types/packages/router/route/action/utils/get-action-name.d.ts +1 -3
  178. package/dist/types/packages/router/route/action/utils/get-controller-name.d.ts +1 -3
  179. package/dist/types/packages/router/route/index.d.ts +13 -9
  180. package/dist/types/packages/router/route/interfaces.d.ts +7 -5
  181. package/dist/types/packages/router/route/params/errors/client-generated-id-error.d.ts +4 -4
  182. package/dist/types/packages/router/route/params/errors/forbidden-parameter-error.d.ts +4 -4
  183. package/dist/types/packages/router/route/params/errors/index.d.ts +1 -0
  184. package/dist/types/packages/router/route/params/errors/invalid-parameter-error.d.ts +4 -6
  185. package/dist/types/packages/router/route/params/errors/parameter-not-nullable-error.d.ts +4 -6
  186. package/dist/types/packages/router/route/params/errors/parameter-range-error.d.ts +9 -0
  187. package/dist/types/packages/router/route/params/errors/parameter-required-error.d.ts +4 -6
  188. package/dist/types/packages/router/route/params/errors/parameter-type-error.d.ts +4 -6
  189. package/dist/types/packages/router/route/params/errors/parameter-value-error.d.ts +4 -6
  190. package/dist/types/packages/router/route/params/errors/resource-mismatch-error.d.ts +4 -6
  191. package/dist/types/packages/router/route/params/index.d.ts +5 -9
  192. package/dist/types/packages/router/route/params/interfaces.d.ts +12 -8
  193. package/dist/types/packages/router/route/params/parameter/forbidden-parameter.d.ts +1 -1
  194. package/dist/types/packages/router/route/params/parameter/ignored-parameter.d.ts +14 -0
  195. package/dist/types/packages/router/route/params/parameter/index.d.ts +21 -5
  196. package/dist/types/packages/router/route/params/parameter/interfaces.d.ts +2 -2
  197. package/dist/types/packages/router/route/params/parameter/utils/validate-range.d.ts +3 -0
  198. package/dist/types/packages/router/route/params/parameter/utils/validate-value.d.ts +1 -3
  199. package/dist/types/packages/router/route/params/parameter-group/index.d.ts +3 -5
  200. package/dist/types/packages/router/route/params/parameter-group/utils/missing-params.d.ts +8 -0
  201. package/dist/types/packages/router/route/params/utils/get-data-params.d.ts +5 -1
  202. package/dist/types/packages/router/route/params/utils/get-default-collection-params.d.ts +1 -3
  203. package/dist/types/packages/router/route/params/utils/get-default-member-params.d.ts +5 -2
  204. package/dist/types/packages/router/route/params/utils/get-query-params.d.ts +3 -9
  205. package/dist/types/packages/router/route/params/utils/get-url-params.d.ts +1 -3
  206. package/dist/types/packages/router/route/params/utils/parse-column-value.d.ts +16 -0
  207. package/dist/types/packages/router/route/params/utils/validate-client-id.d.ts +1 -1
  208. package/dist/types/packages/router/route/params/utils/validate-resource-id.d.ts +1 -3
  209. package/dist/types/packages/router/route/params/utils/validate-type.d.ts +3 -5
  210. package/dist/types/packages/router/route/utils/get-dynamic-segments.d.ts +1 -3
  211. package/dist/types/packages/router/route/utils/get-static-path.d.ts +6 -2
  212. package/dist/types/packages/router/utils/create-replacer.d.ts +10 -2
  213. package/dist/types/packages/serializer/index.d.ts +243 -434
  214. package/dist/types/packages/serializer/interfaces.d.ts +19 -1
  215. package/dist/types/packages/serializer/utils/include-tree.d.ts +12 -3
  216. package/dist/types/packages/serializer/utils/load-linkage.d.ts +9 -3
  217. package/dist/types/packages/server/errors/error-list.d.ts +25 -0
  218. package/dist/types/packages/server/errors/method-not-allowed-error.d.ts +11 -0
  219. package/dist/types/packages/server/index.d.ts +9 -9
  220. package/dist/types/packages/server/interfaces.d.ts +59 -7
  221. package/dist/types/packages/server/request/constants.d.ts +2 -2
  222. package/dist/types/packages/server/request/index.d.ts +3 -5
  223. package/dist/types/packages/server/request/interfaces.d.ts +72 -8
  224. package/dist/types/packages/server/request/parser/errors/malformed-request-error.d.ts +3 -5
  225. package/dist/types/packages/server/request/parser/index.d.ts +6 -1
  226. package/dist/types/packages/server/request/parser/utils/format.d.ts +13 -11
  227. package/dist/types/packages/server/request/parser/utils/normalize-document.d.ts +13 -0
  228. package/dist/types/packages/server/request/parser/utils/parse-nested-object.d.ts +1 -3
  229. package/dist/types/packages/server/request/parser/utils/parse-read.d.ts +2 -4
  230. package/dist/types/packages/server/request/parser/utils/parse-write.d.ts +17 -1
  231. package/dist/types/packages/server/request/utils/get-domain.d.ts +1 -3
  232. package/dist/types/packages/server/responder/index.d.ts +1 -3
  233. package/dist/types/packages/server/responder/utils/content-type-for.d.ts +8 -0
  234. package/dist/types/packages/server/responder/utils/data-for.d.ts +3 -5
  235. package/dist/types/packages/server/responder/utils/normalize.d.ts +2 -3
  236. package/dist/types/packages/server/response/index.d.ts +3 -5
  237. package/dist/types/packages/server/response/interfaces.d.ts +14 -3
  238. package/dist/types/packages/server/utils/client-ip-for.d.ts +10 -0
  239. package/dist/types/packages/server/utils/create-server-error.d.ts +11 -3
  240. package/dist/types/packages/server/utils/request-id-for.d.ts +9 -0
  241. package/dist/types/packages/server/utils/set-cors-headers.d.ts +2 -2
  242. package/dist/types/packages/server/utils/source-for.d.ts +19 -3
  243. package/dist/types/packages/server/utils/status-for-error.d.ts +6 -0
  244. package/dist/types/packages/server/utils/validate-accept.d.ts +1 -1
  245. package/dist/types/packages/server/utils/validate-content-type.d.ts +8 -3
  246. package/dist/types/packages/testing/audit-visibility.d.ts +189 -0
  247. package/dist/types/packages/testing/index.d.ts +4 -0
  248. package/dist/types/packages/testing/start-app.d.ts +52 -0
  249. package/dist/types/packages/testing/utils/identifiers-in.d.ts +14 -0
  250. package/dist/types/testing.d.ts +9 -0
  251. package/dist/types/utils/chalk.d.ts +16 -0
  252. package/dist/types/utils/pick.d.ts +2 -2
  253. package/package.json +54 -26
  254. package/dist/types/packages/cli/commands/test.d.ts +0 -4
  255. package/dist/types/packages/logger/utils/sql.d.ts +0 -4
  256. package/dist/types/packages/router/route/params/parameter-group/utils/has-required-params.d.ts +0 -5
  257. package/dist/types/utils/create-query-string.d.ts +0 -6
  258. package/dist/types/utils/has-own-property.d.ts +0 -1
@@ -1,7 +1,25 @@
1
1
  import type Serializer from './index';
2
2
  import type { Model, ModelClass } from '../database';
3
- export type Serializer$opts<T extends Model> = {
3
+ /**
4
+ * What Lumen constructs a serializer with when the app boots. Apps don't
5
+ * construct serializers themselves.
6
+ */
7
+ export type SerializerOptions<T extends Model> = {
8
+ /** The model of the serializer's type. */
4
9
  model: ModelClass<T>;
10
+ /** The namespace's `application` serializer, if there is one. */
5
11
  parent: Serializer<Model> | null;
12
+ /** The serializer's namespace (`admin`), or `''` for the root. */
6
13
  namespace: string;
7
14
  };
15
+ /**
16
+ * The request's sparse fieldsets: field (attribute and relationship) names
17
+ * keyed by resource type (`fields[users]=name,posts` →
18
+ * `{ users: ['name', 'posts'] }`). An empty list selects no fields.
19
+ */
20
+ export type SerializerFields = Record<string, Array<string>>;
21
+ /**
22
+ * Whether the application serves `GET` at a route key path
23
+ * (`/posts/:dynamic/relationships/user`).
24
+ */
25
+ export type SerializerRouted = (path: string) => boolean;
@@ -4,7 +4,7 @@ import type Serializer from '../index';
4
4
  * A parsed `include` parameter: each relationship name maps to the tree of
5
5
  * relationships to include from the records it points to.
6
6
  *
7
- * @private
7
+ * @internal
8
8
  */
9
9
  export type IncludeTree = Map<string, IncludeTree>;
10
10
  /**
@@ -13,7 +13,7 @@ export type IncludeTree = Map<string, IncludeTree>;
13
13
  * requires the intermediate resources of a multi-part path to be included
14
14
  * along with its leaves (`comments.user` includes the comments too).
15
15
  *
16
- * @private
16
+ * @internal
17
17
  */
18
18
  export declare function createIncludeTree(paths?: Array<string>): IncludeTree;
19
19
  /**
@@ -24,6 +24,15 @@ export declare function createIncludeTree(paths?: Array<string>): IncludeTree;
24
24
  * fallback to the root). Used to build the allowed values of the `include`
25
25
  * parameter.
26
26
  *
27
- * @private
27
+ * @internal
28
28
  */
29
29
  export declare function enumerateIncludePaths(model: ModelClass, names: Array<string>, depth: number, serializerFor?: (model: ModelClass) => Serializer<Model> | undefined): Array<string>;
30
+ /**
31
+ * Every resource type a response can contain, with the Serializer each is
32
+ * serialized by: `model` itself (`serializer`), and every type reachable
33
+ * through `include` from it down to `depth` levels — direct relationships
34
+ * always, as with `include`. Used to build the allowed `fields[TYPE]`.
35
+ *
36
+ * @internal
37
+ */
38
+ export declare function enumerateIncludeTypes(model: ModelClass, serializer: Serializer<Model>, depth: number, serializerFor?: (model: ModelClass) => Serializer<Model> | undefined): Map<string, Serializer<Model>>;
@@ -1,10 +1,11 @@
1
+ import { Scope } from '../../controller/visibility';
1
2
  import type { Model, ModelClass } from '../../database';
2
3
  /**
3
4
  * The resource linkage of one record: the primary key(s) of the records each
4
5
  * named relationship points to — an array for has-many, otherwise a single id
5
6
  * or `null`.
6
7
  *
7
- * @private
8
+ * @internal
8
9
  */
9
10
  export type Linkage = Record<string, Array<string> | string | null>;
10
11
  /**
@@ -17,6 +18,11 @@ export type Linkage = Record<string, Array<string> | string | null>;
17
18
  * many records there are. The queries mirror the lazy relationship getters in
18
19
  * `database/relationship/utils/getters.ts`, which remain the source of truth.
19
20
  *
20
- * @private
21
+ * `scope` hides related records from the linkage: has-one and has-many queries
22
+ * are narrowed by it directly; belongs-to and has-many-through linkage — read
23
+ * from foreign keys, not from the related table — is checked against it
24
+ * afterwards (`dropHidden()`).
25
+ *
26
+ * @internal
21
27
  */
22
- export default function loadLinkage(model: ModelClass, records: Array<Model>, names: Array<string>): Promise<Map<string, Linkage>>;
28
+ export default function loadLinkage(model: ModelClass, records: Array<Model>, names: Array<string>, scope?: Scope): Promise<Map<string, Linkage>>;
@@ -0,0 +1,25 @@
1
+ import type { ServerError } from '../interfaces';
2
+ /**
3
+ * Several problems with one request, reported together: each becomes its own
4
+ * error object in the response's `errors`.
5
+ *
6
+ * @internal
7
+ */
8
+ declare class ErrorList extends Error implements ServerError {
9
+ errors: Array<ServerError>;
10
+ statusCode: number;
11
+ constructor(errors: Array<ServerError>);
12
+ /**
13
+ * The error to throw for `errors`: the only one, or a list of them.
14
+ */
15
+ static from(errors: Array<ServerError>): ServerError;
16
+ }
17
+ /**
18
+ * Run each of `steps`, collecting the server errors (those with a
19
+ * `statusCode`) they throw instead of stopping at the first; anything else
20
+ * is a bug and is rethrown at once. Throws the collected errors, if any.
21
+ *
22
+ * @internal
23
+ */
24
+ export declare function collectErrors(steps: Array<() => void>, errors?: Array<ServerError>): void;
25
+ export default ErrorList;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A request whose path exists, but not for its method. The responder's
3
+ * caller sets the `Allow` header listing the methods that are.
4
+ *
5
+ * @internal
6
+ */
7
+ declare class MethodNotAllowedError extends Error {
8
+ constructor(method: string, allowed: Array<string>);
9
+ }
10
+ declare const _default: new (...args: Array<any>) => MethodNotAllowedError & import("..").ServerError;
11
+ export default _default;
@@ -4,25 +4,25 @@ import type Logger from '../logger';
4
4
  import type Router from '../router';
5
5
  import type { Request } from './request/interfaces';
6
6
  import type { Response } from './response/interfaces';
7
- import type { Server$opts, Server$cors } from './interfaces';
8
- /**
9
- * @private
10
- */
7
+ import type { ServerOptions, CorsConfig } from './interfaces';
8
+ /** @internal */
11
9
  declare class Server {
12
10
  logger: Logger;
13
11
  router: Router;
14
- cors: Server$cors;
12
+ cors: CorsConfig;
13
+ trustProxy: boolean;
15
14
  instance: HTTPServer;
16
- constructor({ logger, router, cors }: Server$opts);
15
+ constructor({ logger, router, cors, trustProxy }: ServerOptions);
17
16
  listen(port: number): void;
18
17
  initializeRequest(req: IncomingMessage, res: Writable): [Request, Response];
19
- validateRequest({ method, headers }: Request): true;
18
+ validateRequest({ method, headers, route }: Request): true;
20
19
  receiveRequest: (req: IncomingMessage, res: Writable) => void;
21
20
  }
22
21
  export default Server;
23
22
  export { REQUEST_METHODS, getDomain } from './request';
24
23
  export { default as createServerError } from './utils/create-server-error';
25
24
  export { default as sourceFor } from './utils/source-for';
26
- export type { Server$config, Server$ErrorSource } from './interfaces';
27
- export type { Request, Request$params, Request$method } from './request/interfaces';
25
+ export { default as ErrorList } from './errors/error-list';
26
+ export type { CorsConfig, ServerConfig, ServerError, ServerErrorSource } from './interfaces';
27
+ export type { Request, RequestParams, RequestMethod } from './request/interfaces';
28
28
  export type { Response } from './response/interfaces';
@@ -1,23 +1,75 @@
1
1
  import type Logger from '../logger';
2
2
  import type Router from '../router';
3
- export type Server$cors = {
3
+ /**
4
+ * CORS headers for every response, so browsers on another origin may call
5
+ * the API:
6
+ *
7
+ * ```javascript
8
+ * cors: {
9
+ * enabled: true,
10
+ * origin: 'https://app.example.com',
11
+ * headers: ['Accept', 'Content-Type', 'Authorization'],
12
+ * methods: ['GET', 'POST', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
13
+ * }
14
+ * ```
15
+ */
16
+ export type CorsConfig = {
17
+ /** Whether to send the headers at all. Off by default. */
4
18
  enabled: boolean;
19
+ /** `Access-Control-Allow-Origin`: the origin allowed, or `*`. */
5
20
  origin?: string;
21
+ /** `Access-Control-Allow-Headers`: the request headers allowed. */
6
22
  headers?: Array<string>;
23
+ /** `Access-Control-Allow-Methods`: the methods allowed. */
7
24
  methods?: Array<string>;
8
25
  };
9
- export type Server$config = {
10
- cors: Server$cors;
26
+ /**
27
+ * The `server` section of `config/environments/<environment>.js`.
28
+ */
29
+ export type ServerConfig = {
30
+ /** CORS headers; off by default. */
31
+ cors: CorsConfig;
32
+ /**
33
+ * Whether one proxy sits in front of the app (Heroku's router, a load
34
+ * balancer) whose `X-Forwarded-For` entry is the client's address. Only
35
+ * enable it behind such a proxy: without one, clients can set the header to
36
+ * anything.
37
+ */
38
+ trustProxy?: boolean;
39
+ /**
40
+ * How long, in milliseconds, `lumen serve` lets a worker finish the
41
+ * requests in flight when it stops (`SIGTERM`, `SIGINT`) before killing
42
+ * it. Defaults to `8000`: within Docker's 10 s grace period, and Heroku's
43
+ * and Kubernetes' 30 s.
44
+ */
45
+ shutdownTimeout?: number;
11
46
  };
12
- export type Server$opts = Server$config & {
47
+ export type ServerOptions = ServerConfig & {
13
48
  logger: Logger;
14
49
  router: Router;
15
50
  };
16
- export type Server$ErrorSource = {
51
+ export type ServerErrorSource = {
17
52
  pointer?: string;
18
53
  parameter?: string;
19
54
  };
20
- export interface Server$Error extends Error {
55
+ /**
56
+ * An error a request is answered with. Besides `statusCode`, it may carry the
57
+ * members of its JSON:API error object: `source` points into the request;
58
+ * `id`, `code`, `title`, `meta` and `links.about` are passed through as set.
59
+ * (`detail` is the message, exposed only in development, when it starts
60
+ * with `[public]`, or for the framework's own client errors, which set
61
+ * `isPublic`.)
62
+ */
63
+ export interface ServerError extends Error {
21
64
  statusCode: number;
22
- source?: Server$ErrorSource;
65
+ source?: ServerErrorSource;
66
+ id?: string;
67
+ code?: string;
68
+ title?: string;
69
+ meta?: Record<string, unknown>;
70
+ links?: {
71
+ about: string;
72
+ };
73
+ /** @internal */
74
+ isPublic?: boolean;
23
75
  }
@@ -1,2 +1,2 @@
1
- import type { Request$method } from './interfaces';
2
- export declare const REQUEST_METHODS: Array<Request$method>;
1
+ import type { RequestMethod } from './interfaces';
2
+ export declare const REQUEST_METHODS: Array<RequestMethod>;
@@ -1,8 +1,6 @@
1
- import type { Request, Request$opts } from './interfaces';
2
- /**
3
- * @private
4
- */
5
- export declare function createRequest(req: any, { logger, router }: Request$opts): Request;
1
+ import type { Request, RequestOptions } from './interfaces';
2
+ /** @internal */
3
+ export declare function createRequest(req: any, { logger, router }: RequestOptions): Request;
6
4
  export { REQUEST_METHODS } from './constants';
7
5
  export { parseRequest } from './parser';
8
6
  export { default as getDomain } from './utils/get-domain';
@@ -4,11 +4,11 @@ import type Logger from '../../logger';
4
4
  import type Router from '../../router';
5
5
  import type { Route } from '../../router';
6
6
  import type Controller from '../../controller';
7
- export type Request$opts = {
7
+ export type RequestOptions = {
8
8
  logger: Logger;
9
9
  router: Router;
10
10
  };
11
- type Request$url = {
11
+ type RequestUrl = {
12
12
  protocol?: string;
13
13
  slashes?: boolean;
14
14
  auth?: string;
@@ -23,41 +23,105 @@ type Request$url = {
23
23
  path: string;
24
24
  href: string;
25
25
  };
26
- export type Request$method = 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'DELETE';
27
- export type Request$params = {
26
+ /** An HTTP method Lumen routes. */
27
+ export type RequestMethod = 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'DELETE';
28
+ /**
29
+ * A request's parameters, parsed and validated: `request.params`. Member
30
+ * names are camelCase whatever the client sent. Only what the request
31
+ * carries is present; query parameters a controller lists in
32
+ * {@link Controller.query} appear under their own names.
33
+ */
34
+ export type RequestParams = {
35
+ /** The route's `:id`: a number for an integer primary key. */
28
36
  id: number | string | Buffer;
37
+ /** `?sort=`: an attribute, `-` first for descending. */
29
38
  sort: string;
39
+ /** `?filter[…]=`, by attribute; a comma-separated value is a list. */
30
40
  filter: Record<string, unknown>;
41
+ /** `?fields[…]=`: the fields to serialize, by resource type. */
31
42
  fields: Record<string, unknown>;
43
+ /** `?include=`: relationship paths (`comments.user`). */
32
44
  include: Array<string>;
45
+ /** `?page[…]=`. */
33
46
  page: {
47
+ /** `page[size]`. */
34
48
  size?: number;
49
+ /** `page[number]`, counting from 1. */
35
50
  number?: number;
36
51
  };
52
+ /** The body's primary data, on `POST` and `PATCH`. */
37
53
  data: {
54
+ /** The resource's id (`PATCH`). */
38
55
  id: number | string | Buffer;
56
+ /** The resource type. */
39
57
  type: string;
58
+ /** The attributes the controller accepts. */
40
59
  attributes?: Record<string, unknown>;
60
+ /** The relationships, each as `{ data }` linkage. */
41
61
  relationships?: Record<string, unknown>;
42
62
  };
43
63
  };
64
+ /**
65
+ * The request an action or hook receives: Node's incoming message, with
66
+ * Lumen's parsed parameters and routing.
67
+ */
44
68
  export interface Request extends Readable {
69
+ /**
70
+ * Identifies the request in the logs and the `X-Request-Id` response
71
+ * header: the client's own `X-Request-Id` when it is well-formed, otherwise
72
+ * a fresh UUID.
73
+ */
74
+ id: string;
75
+ /**
76
+ * The client's address: the connection's, or — with `server.trustProxy` —
77
+ * the one the proxy in front added to `X-Forwarded-For`.
78
+ */
79
+ ip?: string;
80
+ /**
81
+ * The headers, by lowercase name, as a `Map`:
82
+ * `request.headers.get('authorization')`.
83
+ */
45
84
  headers: Map<string, string>;
85
+ /** The HTTP version, `'1.1'`. */
46
86
  httpVersion: string;
47
- method: Request$method;
87
+ /** The method, or an `X-HTTP-Method-Override` header's. */
88
+ method: RequestMethod;
89
+ /** Node's request trailers. */
48
90
  trailers: Record<string, unknown>;
91
+ /** The connection's socket. */
49
92
  socket: Socket;
93
+ /** The application's logger. */
50
94
  logger: Logger;
51
- params: Request$params;
52
- defaultParams: Request$params;
95
+ /** @internal */
96
+ router: Router;
97
+ /** The parsed, validated parameters. */
98
+ params: RequestParams;
99
+ /**
100
+ * The parsed JSON body of a `POST` or `PATCH`, as the client sent it. On a
101
+ * plain route (neither `member` nor `collection`) it is any JSON, and is
102
+ * not validated: read it here, not in `params`. `undefined` without a body.
103
+ */
104
+ body?: unknown;
105
+ /** @internal */
106
+ defaultParams: RequestParams;
107
+ /**
108
+ * The matched route. `route.type` is `'relationship'` or `'related'` on a
109
+ * relationship or related endpoint, and `route.relationship` names the
110
+ * relationship there.
111
+ */
53
112
  route: Route;
113
+ /** The name of the action handling the request (`'index'`). */
54
114
  action: string;
115
+ /** The controller handling the request. */
55
116
  controller: Controller;
56
- url: Request$url;
117
+ /** The parsed URL: `pathname`, `query` and the rest. */
118
+ url: RequestUrl;
119
+ /** @internal */
57
120
  connection: {
58
121
  encrypted: boolean;
59
122
  remoteAddress: string;
60
123
  };
124
+ /** Node's `setTimeout` for the request. */
61
125
  setTimeout(msecs: number, callback: () => void): void;
62
126
  }
63
127
  export {};
@@ -1,8 +1,6 @@
1
- /**
2
- * @private
3
- */
1
+ /** @internal */
4
2
  declare class MalformedRequestError extends SyntaxError {
5
- constructor();
3
+ constructor(expected?: string);
6
4
  }
7
- declare const _default: new (...args: Array<any>) => MalformedRequestError & import("../../../interfaces").Server$Error;
5
+ declare const _default: new (...args: Array<any>) => MalformedRequestError & import("../../..").ServerError;
8
6
  export default _default;
@@ -1,5 +1,10 @@
1
1
  import type { Request } from '../interfaces';
2
2
  /**
3
- * @private
3
+ * The request's parameters: the query string's, and on `POST` and `PATCH`
4
+ * the body's. A plain route's body is any JSON, kept as `request.body` and
5
+ * not validated; a resource route's is a JSON:API document, normalized into
6
+ * the parameters (`data`) and also kept as `request.body`.
7
+ *
8
+ * @internal
4
9
  */
5
10
  export declare function parseRequest(req: Request): Promise<Record<string, unknown>>;
@@ -1,17 +1,19 @@
1
- import type { Request$method } from '../../interfaces';
2
- /**
3
- * @private
4
- */
1
+ /** @internal */
5
2
  export declare function formatSort(sort: string): string;
3
+ /** @internal */
4
+ export declare function formatFields(fields: Record<string, unknown>): Record<string, Array<string>>;
6
5
  /**
7
- * @private
8
- */
9
- export declare function formatFields(fields: Record<string, unknown>): Record<string, unknown>;
10
- /**
11
- * @private
6
+ * Relationship paths, with each member name camelized
7
+ * (`comments.blog-author` -> `comments.blogAuthor`).
8
+ *
9
+ * @internal
12
10
  */
13
11
  export declare function formatInclude(include: string | Array<string>): Array<string>;
14
12
  /**
15
- * @private
13
+ * Format query parameters: keys are camelized (they are member names, e.g.
14
+ * `filter[is-public]`), values are coerced (`123`, `true`, `null`, ISO dates)
15
+ * and split on commas, but otherwise left as written.
16
+ *
17
+ * @internal
16
18
  */
17
- export default function format(params: Record<string, unknown>, method: Request$method): Record<string, unknown>;
19
+ export default function format(params: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Bring a request document's member names into their internal form: the
3
+ * names of `data.attributes` and `data.relationships` are camelized
4
+ * (`is-public` -> `isPublic`). Nothing else is touched — in particular no
5
+ * value: attribute values (and keys inside them) are data, and ids and dates
6
+ * are typed by parameter validation, from the columns they are written to.
7
+ *
8
+ * Anything that is not a resource document is passed through for parameter
9
+ * validation to reject.
10
+ *
11
+ * @internal
12
+ */
13
+ export default function normalizeDocument(document: unknown): unknown;
@@ -1,4 +1,2 @@
1
- /**
2
- * @private
3
- */
1
+ /** @internal */
4
2
  export default function parseNestedObject(source: Record<string, unknown>): Record<string, unknown>;
@@ -1,5 +1,3 @@
1
1
  import type { Request } from '../../interfaces';
2
- /**
3
- * @private
4
- */
5
- export default function parseRead({ method, url: { query } }: Request): Record<string, unknown>;
2
+ /** @internal */
3
+ export default function parseRead({ url: { query } }: Request): Record<string, unknown>;
@@ -1,5 +1,21 @@
1
1
  import type { Request } from '../../interfaces';
2
2
  /**
3
- * @private
3
+ * The request body, read to the end as text.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare function readBody(req: Request): Promise<string>;
8
+ /**
9
+ * A plain route's body: any JSON, as sent, or `undefined` when there is
10
+ * none. Nothing in it is validated or renamed.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function parseJSON(req: Request): Promise<unknown>;
15
+ /**
16
+ * A JSON:API document's members, normalized into the request's parameters.
17
+ * The document as sent is also `request.body`.
18
+ *
19
+ * @internal
4
20
  */
5
21
  export default function parseWrite(req: Request): Promise<Record<string, unknown>>;
@@ -1,5 +1,3 @@
1
1
  import type { Request } from '../interfaces';
2
- /**
3
- * @private
4
- */
2
+ /** @internal */
5
3
  export default function getDomain({ headers, connection: { encrypted } }: Request): string;
@@ -1,5 +1,3 @@
1
1
  import type { Request, Response } from '../index';
2
- /**
3
- * @private
4
- */
2
+ /** @internal */
5
3
  export declare function createResponder(req: Request, res: Response): (data?: unknown) => void;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The `Content-Type` of a response body, before it is serialized: the
3
+ * JSON:API media type for a JSON:API document, `application/json` for any
4
+ * other object or array, plain text for a string, and none for an empty body.
5
+ *
6
+ * @internal
7
+ */
8
+ export default function contentTypeFor(body: unknown): string | undefined;
@@ -1,5 +1,3 @@
1
- import type { JSONAPI$Document } from '../../../jsonapi';
2
- /**
3
- * @private
4
- */
5
- export default function dataFor(status: number, err?: Error): string | JSONAPI$Document;
1
+ import type { JsonApiDocument } from '../../../jsonapi';
2
+ /** @internal */
3
+ export default function dataFor(status: number, err?: Error): string | JsonApiDocument;
@@ -1,7 +1,6 @@
1
- /**
2
- * @private
3
- */
1
+ /** @internal */
4
2
  export default function normalize(data?: unknown): {
5
3
  statusCode: number | undefined;
4
+ body: unknown;
6
5
  data: string;
7
6
  };
@@ -1,5 +1,3 @@
1
- import type { Response, Response$opts } from './interfaces';
2
- /**
3
- * @private
4
- */
5
- export declare function createResponse(res: any, opts: Response$opts): Response;
1
+ import type { Response, ResponseOptions } from './interfaces';
2
+ /** @internal */
3
+ export declare function createResponse(res: any, opts: ResponseOptions): Response;
@@ -1,22 +1,33 @@
1
1
  import type { Writable } from 'stream';
2
2
  import type Logger from '../../logger';
3
- type Response$stat = {
3
+ type ResponseStat = {
4
4
  type: string;
5
5
  name: string;
6
6
  duration: number;
7
7
  controller: string;
8
8
  };
9
- export type Response$opts = {
9
+ export type ResponseOptions = {
10
10
  logger: Logger;
11
11
  };
12
+ /**
13
+ * The response an action or hook receives: Node's server response. Use it
14
+ * for headers, or for a status the action's return value doesn't decide.
15
+ */
12
16
  export interface Response extends Writable {
13
17
  [key: string]: unknown;
14
- stats: Array<Response$stat>;
18
+ /** @internal */
19
+ stats: Array<ResponseStat>;
20
+ /** The application's logger. */
15
21
  logger: Logger;
22
+ /** The status code to send. */
16
23
  statusCode: number;
24
+ /** The status message to send; defaults to the code's standard one. */
17
25
  statusMessage: string;
26
+ /** A header set so far. */
18
27
  getHeader(name: string): string | void;
28
+ /** Set a header. */
19
29
  setHeader(name: string, value: string): void;
30
+ /** Remove a header set earlier. */
20
31
  removeHeader(name: string): void;
21
32
  }
22
33
  export {};
@@ -0,0 +1,10 @@
1
+ import type { Request } from '../request/interfaces';
2
+ /**
3
+ * The client's address. Behind a trusted proxy that is the *last*
4
+ * `X-Forwarded-For` entry — the one the proxy appended; anything before it
5
+ * came from the client and could be forged. Otherwise it is the connection's
6
+ * own address.
7
+ *
8
+ * @internal
9
+ */
10
+ export default function clientIpFor({ headers, socket }: Request, trustProxy?: boolean): string | undefined;
@@ -1,7 +1,15 @@
1
- import type { Server$Error } from '../interfaces';
1
+ import type { ServerError } from '../interfaces';
2
2
  type Constructor<T> = new (...args: Array<any>) => T;
3
3
  /**
4
- * @private
4
+ * `Target`, answered with `statusCode`. `isPublic` marks a client error whose
5
+ * message only describes the request — echoed input and declared names, never
6
+ * stored data, SQL or internals — so it is the error's `detail` in every
7
+ * environment. Leave it off for anything that passes on another message (a
8
+ * database driver's, say).
9
+ *
10
+ * @internal
5
11
  */
6
- export default function createServerError<T extends object>(Target: Constructor<T>, statusCode: number): Constructor<T & Server$Error>;
12
+ export default function createServerError<T extends object>(Target: Constructor<T>, statusCode: number, { isPublic }?: {
13
+ isPublic?: boolean;
14
+ }): Constructor<T & ServerError>;
7
15
  export {};
@@ -0,0 +1,9 @@
1
+ import type { Request } from '../request/interfaces';
2
+ /**
3
+ * The id a request is logged and answered with: the client's (or a proxy's)
4
+ * own `X-Request-Id` when it is well-formed, so a request can be traced
5
+ * across services, otherwise a fresh UUID.
6
+ *
7
+ * @internal
8
+ */
9
+ export default function requestIdFor({ headers }: Request): string;
@@ -1,3 +1,3 @@
1
1
  import type { Response } from '../index';
2
- import type { Server$cors } from '../interfaces';
3
- export default function setCORSHeaders(res: Response, { origin, methods, headers, enabled }: Server$cors): void;
2
+ import type { CorsConfig } from '../interfaces';
3
+ export default function setCORSHeaders(res: Response, { origin, methods, headers, enabled }: CorsConfig): void;