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
@@ -3,80 +3,74 @@ import ChangeSet from '../change-set';
3
3
  import type Logger from '../../logger';
4
4
  import type Database from '../../database';
5
5
  import type Serializer from '../../serializer';
6
- import type { Relationship$opts } from '../relationship';
7
- import type { ModelClass, Database$column } from '../interfaces';
8
- import type { Transaction$ResultProxy } from '../transaction';
9
- import type { Model$Hooks } from './interfaces';
6
+ import type { RelationshipOptions } from '../relationship';
7
+ import type { ModelClass, DatabaseColumn } from '../interfaces';
8
+ import type { TransactionResult } from '../transaction';
9
+ import type { ModelHooks } from './interfaces';
10
10
  /**
11
- * @class Model
12
- * @public
11
+ * The base class of an app's models. A model is one database table: its
12
+ * attributes are the table's columns, read when the app boots, and the class
13
+ * declares the rest as statics — relationships (`hasOne`, `hasMany`,
14
+ * `belongsTo`), `validates`, `hooks` and `scopes`.
15
+ *
16
+ * ```javascript
17
+ * import { Model } from 'lumen-framework';
18
+ *
19
+ * class Post extends Model {
20
+ * static belongsTo = {
21
+ * user: { inverse: 'posts' }
22
+ * };
23
+ * }
24
+ *
25
+ * export default Post;
26
+ * ```
27
+ *
28
+ * Relationships are checked when the app boots: each `inverse` must name a
29
+ * relationship on the related model that points back, of a kind that pairs
30
+ * with it, and each foreign key must be a column. A mistake fails the boot,
31
+ * naming the relationship.
32
+ *
33
+ * The static query methods (`find`, `where`, `first`, …) start a
34
+ * {@link Query}; `create`, and `update`, `save` and `destroy` on a record,
35
+ * write. See the
36
+ * [models guide](https://github.com/nickschot/lux/blob/main/docs/guides/models.md).
13
37
  */
14
38
  declare class Model {
39
+ /**
40
+ * The record's model class, typed with its statics
41
+ * (`this.constructor.primaryKey`, `.relationshipFor`, …).
42
+ */
15
43
  ['constructor']: ModelClass;
16
44
  /**
17
- * The name of the corresponding database table for a `Model` instance's
18
- * constructor.
19
- *
20
- * @property tableName
21
- * @type {String}
22
- * @public
45
+ * The model's table name; the same as the static {@link Model.tableName}.
23
46
  */
24
47
  tableName: string;
25
48
  /**
26
- * The canonical name of a `Model`'s constructor.
27
- *
28
- * @property modelName
29
- * @type {String}
30
- * @public
49
+ * The model's name (`post`); the same as the static
50
+ * {@link Model.modelName}.
31
51
  */
32
52
  modelName: string;
33
53
  /**
34
- * The name of the API resource a `Model` instance's constructor represents.
35
- *
36
- * @property resourceName
37
- * @type {String}
38
- * @public
54
+ * The resource type the model is served as (`posts`); the same as the
55
+ * static {@link Model.resourceName}.
39
56
  */
40
57
  resourceName: string;
41
58
  /**
42
- * A timestamp representing when the Model instance was created.
43
- *
44
- * @property createdAt
45
- * @type {Date}
46
- * @public
59
+ * When the record was created, if the table has a `created_at` column.
47
60
  */
48
61
  createdAt: Date;
49
62
  /**
50
- * A timestamp representing the last time the Model instance was updated.
51
- *
52
- * @property updatedAt
53
- * @type {Date}
54
- * @public
63
+ * When the record was last updated, if the table has an `updated_at`
64
+ * column.
55
65
  */
56
66
  updatedAt: Date;
57
- /**
58
- * @property initialized
59
- * @type {Boolean}
60
- * @private
61
- */
67
+ /** @internal */
62
68
  initialized: boolean;
63
- /**
64
- * @property rawColumnData
65
- * @type {Object}
66
- * @private
67
- */
69
+ /** @internal */
68
70
  rawColumnData: Record<string, unknown>;
69
- /**
70
- * @property isModelInstance
71
- * @type {Boolean}
72
- * @private
73
- */
71
+ /** @internal */
74
72
  isModelInstance: boolean;
75
- /**
76
- * @property prevAssociations
77
- * @type {Set}
78
- * @private
79
- */
73
+ /** @internal */
80
74
  prevAssociations: Set<Model>;
81
75
  /**
82
76
  * Names of `hasOne` relationships that were eager-loaded (joined) and found
@@ -84,974 +78,569 @@ declare class Model {
84
78
  * without a per-record query. Kept outside of the change sets so it never
85
79
  * counts as a change to the record.
86
80
  *
87
- * @property absentRelationships
88
- * @type {Set}
89
- * @private
81
+ * @internal
90
82
  */
91
83
  absentRelationships: Set<string>;
92
- /**
93
- * @property changeSets
94
- * @type {Array}
95
- * @private
96
- */
84
+ /** @internal */
97
85
  changeSets: Array<ChangeSet>;
98
86
  /**
99
- * An object where you declare `hasOne` relationships.
100
- *
101
- * When declaring a relationship you must specify the inverse of the
102
- * relationship.
87
+ * The model's to-one relationships whose foreign key is on the *other*
88
+ * table, by name. Each names its `inverse`, the relationship on the other
89
+ * model that points back:
103
90
  *
104
91
  * ```javascript
105
92
  * class User extends Model {
106
93
  * static hasOne = {
107
- * profile: {
108
- * inverse: 'user'
109
- * // The line above lets Lumen know that this relationship is accessible
110
- * // on profile instances via `profile.user`.
111
- * }
94
+ * profile: { inverse: 'user' } // profiles.user_id
112
95
  * };
113
96
  * }
114
97
  *
115
98
  * class Profile extends Model {
116
99
  * static belongsTo = {
117
- * user: {
118
- * inverse: 'profile'
119
- * // The line above lets Lumen know that this relationship is accessible
120
- * // on user instances via `user.profile`.
121
- * }
100
+ * user: { inverse: 'profile' }
122
101
  * };
123
102
  * }
124
103
  * ```
125
104
  *
126
- * If the name of the model is different than the key of the relationship, you
127
- * must specify it in the relationship object.
128
- *
129
- * ```javascript
130
- * class Profile extends Model {
131
- * static belongsTo = {
132
- * owner: {
133
- * inverse: 'profile',
134
- * model: 'user'
135
- * // The line above lets Lumen know that this is a relationship with the
136
- * // `User` model and not a non-existent `Owner` model.
137
- * }
138
- * };
139
- * }
140
- * ```
141
- *
142
- * @property hasOne
143
- * @type {Object}
144
- * @default {}
145
- * @static
146
- * @public
105
+ * The foreign key is on the other table: its inverse `belongsTo`'s, which
106
+ * is `<inverse>_id` unless that declares a `foreignKey`. Set `model` when
107
+ * the related model's name differs from the relationship's
108
+ * (`avatar: { inverse: 'owner', model: 'image' }`).
147
109
  */
148
110
  static hasOne: Record<string, unknown>;
149
111
  /**
150
- * An object where you declare `hasMany` relationships.
151
- *
152
- * When declaring a relationship you must specify the inverse of the
153
- * relationship.
112
+ * The model's to-many relationships, by name. Each names its `inverse`, the
113
+ * relationship on the other model that points back:
154
114
  *
155
115
  * ```javascript
156
116
  * class Author extends Model {
157
117
  * static hasMany = {
158
- * books: {
159
- * inverse: 'author'
160
- * // The line above lets Lumen know that this relationship is accessible
161
- * // on book instances via `book.author`.
162
- * }
118
+ * books: { inverse: 'author' } // books.author_id
163
119
  * };
164
120
  * }
165
121
  *
166
122
  * class Book extends Model {
167
123
  * static belongsTo = {
168
- * author: {
169
- * inverse: 'books'
170
- * // The line above lets Lumen know that this relationship is accessible
171
- * // on author instances via `author.books`.
172
- * }
124
+ * author: { inverse: 'books' }
173
125
  * };
174
126
  * }
175
127
  * ```
176
128
  *
177
- * If the name of the model is different than the key of the relationship, you
178
- * must specify it in the relationship object.
129
+ * The foreign key is on the other table: its inverse `belongsTo`'s, which
130
+ * is `<inverse>_id` unless that declares a `foreignKey`. Set `model` when
131
+ * the related model's name differs from the relationship's
132
+ * (`publications: { inverse: 'author', model: 'book' }`).
133
+ *
134
+ * A many-to-many relationship goes `through` a join model, which
135
+ * `belongsTo` both sides; each side's `inverse` names the other side's
136
+ * relationship:
179
137
  *
180
138
  * ```javascript
181
- * class Author extends Model {
139
+ * class Post extends Model {
182
140
  * static hasMany = {
183
- * publications: {
184
- * inverse: 'author',
185
- * model: 'book'
186
- * // The line above lets Lumen know that this is a relationship with the
187
- * // `Book` model and not a non-existent `Publication` model.
188
- * }
141
+ * tags: { inverse: 'posts', through: 'categorization' }
189
142
  * };
190
143
  * }
191
- * ```
192
- *
193
- * ##### Many to Many
194
- *
195
- * In the examples above there is only one owner of relationship. Sometimes we
196
- * need to express a many to many relationship. Typically in relational
197
- * databases, this is done with a join table. When declaring a many to many
198
- * relationship that uses a join table, you must specify the join model.
199
- *
200
- * ```javascript
201
- * class Categorization extends Model {
202
- * static belongsTo = {
203
- * tag: {
204
- * inverse: 'categorization'
205
- * },
206
- * post: {
207
- * inverse: 'categorization'
208
- * }
209
- * }
210
- * }
211
144
  *
212
145
  * class Tag extends Model {
213
146
  * static hasMany = {
214
- * posts: {
215
- * inverse: 'tags',
216
- * through: 'categorizations'
217
- * }
147
+ * posts: { inverse: 'tags', through: 'categorization' }
218
148
  * };
219
149
  * }
220
150
  *
221
- * class Post extends Model {
222
- * static hasMany = {
223
- * tags: {
224
- * inverse: 'posts',
225
- * through: 'categorizations'
226
- * }
151
+ * class Categorization extends Model {
152
+ * static belongsTo = {
153
+ * post: { inverse: 'tags' },
154
+ * tag: { inverse: 'posts' }
227
155
  * };
228
156
  * }
229
157
  * ```
230
- *
231
- * @property hasMany
232
- * @type {Object}
233
- * @default {}
234
- * @static
235
- * @public
236
158
  */
237
159
  static hasMany: Record<string, unknown>;
238
160
  /**
239
- * An object where you declare `belongsTo` relationships.
240
- *
241
- * When declaring a relationship you must specify the inverse of the
242
- * relationship.
161
+ * The model's to-one relationships whose foreign key is on *this* table,
162
+ * by name. Each names its `inverse`, the relationship on the other model
163
+ * that points back:
243
164
  *
244
165
  * ```javascript
245
166
  * class Book extends Model {
246
167
  * static belongsTo = {
247
- * author: {
248
- * inverse: 'books'
249
- * // The line above lets Lumen know that this relationship is accessible
250
- * // on author instances via `author.books`.
251
- * }
168
+ * author: { inverse: 'books' } // books.author_id
252
169
  * };
253
170
  * }
254
171
  *
255
172
  * class Author extends Model {
256
173
  * static hasMany = {
257
- * books: {
258
- * inverse: 'book'
259
- * // The line above lets Lumen know that this relationship is accessible
260
- * // on book instances via `book.author`.
261
- * }
262
- * };
263
- * }
264
- * ```
265
- *
266
- * If the name of the model is different than the key of the relationship, you
267
- * must specify it in the relationship object.
268
- *
269
- * ```javascript
270
- * class Book extends Model {
271
- * static belongsTo = {
272
- * writer: {
273
- * inverse: 'books',
274
- * model: 'author'
275
- * // The line above lets Lumen know that this is a relationship with the
276
- * // `Author` model and not a non-existent `Writer` model.
277
- * }
174
+ * books: { inverse: 'author' }
278
175
  * };
279
176
  * }
280
177
  * ```
281
178
  *
282
- * Sometimes our foreign keys in the database do not follow conventions (i.e
283
- * `author_id`). You have the option to manually specify foreign keys when a
284
- * situation like this occurs.
179
+ * The foreign key is `<name>_id` on this table, and is also an attribute
180
+ * (`book.authorId`), so the relationship can be set by id as well as by
181
+ * record. Set `model` when the related model's name differs from the
182
+ * relationship's, and `foreignKey` for a column named otherwise:
285
183
  *
286
184
  * ```javascript
287
185
  * class Book extends Model {
288
186
  * static belongsTo = {
289
- * author: {
290
- * inverse: 'books',
291
- * foreignKey: 'SoMe_UnCoNvEnTiOnAl_FoReIgN_KeY'
292
- * }
187
+ * writer: { inverse: 'books', model: 'author', foreignKey: 'written_by' }
293
188
  * };
294
189
  * }
295
190
  * ```
296
191
  *
297
- * @property belongsTo
298
- * @type {Object}
299
- * @default {}
300
- * @static
301
- * @public
192
+ * The `hasOne` or `hasMany` on the other side uses the same column without
193
+ * declaring it.
302
194
  */
303
195
  static belongsTo: Record<string, unknown>;
304
196
  /**
305
- * An object where you declare validations for an instance's attributes.
306
- *
307
- * Before a model instance is saved, validations declared in this block are
308
- * executed. To declare a validation for a model attribute, simply add the
309
- * attribute name as a key to the validates object. The value for the
310
- * attribute key should be a function that takes a single argument (the value
311
- * to validate against) and return a boolean value represent whether or not
312
- * the attribute is valid.
313
- *
314
- * ```javascript
315
- * class User extends Model {
316
- * static validates {
317
- * username: value => /^\w{2,30}$/.test(value),
318
- * password: value => String(value).length >= 8
319
- * };
320
- * }
321
- * ```
322
- *
323
- * In the spirit of have a small api surface area, Lumen provides no validation
324
- * helper functions. You can roll your own helpers with or use one of the many
325
- * excellent validation libraries like [validator](https://goo.gl/LWaHBB).
197
+ * Validators for the model's attributes, by attribute name. Each takes the
198
+ * value and returns whether it is valid; they run before every create and
199
+ * update, after the `beforeValidation` hooks.
326
200
  *
327
201
  * ```javascript
328
202
  * import { isEmail } from 'validator';
329
203
  *
330
204
  * class User extends Model {
331
- * static validates {
332
- * email: isEmail
205
+ * static validates = {
206
+ * email: isEmail,
207
+ * username: value => /^\w{2,30}$/.test(value)
333
208
  * };
334
209
  * }
335
210
  * ```
336
211
  *
337
- * @property validates
338
- * @type {Object}
339
- * @default {}
340
- * @static
341
- * @public
212
+ * A value that fails throws a `ValidationError`, which the API answers
213
+ * with `422 Unprocessable Entity` and a pointer to the attribute. Lumen
214
+ * ships no validators of its own; use plain functions or a package such as
215
+ * [validator](https://www.npmjs.com/package/validator).
342
216
  */
343
217
  static validates: Record<string, unknown>;
344
218
  /**
345
- * An object where you declare custom query scopes for the model.
346
- *
347
- * Scopes allow you to DRY up query logic by chaining custom set's of queries
348
- * with built-in query method such as `where`, `not`, `page`, etc. To declare
349
- * a scope, add it as a method on the scopes object.
219
+ * Named, reusable query conditions. Each scope becomes a method on the
220
+ * model and on its queries, with `this` the query it is called on, and
221
+ * chains like the built-in methods:
350
222
  *
351
223
  * ```javascript
352
224
  * class Post extends Model {
353
- * static hasMany = {
354
- * tags: {
355
- * inverse: 'posts'
356
- * },
357
- * comments: {
358
- * inverse: 'post'
359
- * }
360
- * };
361
- *
362
- * static belongsTo = {
363
- * user: {
364
- * inverse: 'posts'
365
- * }
366
- * };
367
- *
368
225
  * static scopes = {
369
226
  * isPublic() {
370
- * return this.where({
371
- * isPublic: true
372
- * });
227
+ * return this.where({ isPublic: true });
373
228
  * },
374
229
  *
375
230
  * byUser(user) {
376
- * return this.where({
377
- * userId: user.id
378
- * });
379
- * },
380
- *
381
- * withEverything() {
382
- * return this.includes('tags', 'user', 'comments');
231
+ * return this.where({ userId: user.id });
383
232
  * }
384
233
  * };
385
234
  * }
386
- * ```
387
- *
388
- * Given the scopes declared in the example above, here is how we could return
389
- * all the public posts with relationships eager loaded for the user with the
390
- * id of 1.
391
235
  *
392
- * ```javascript
393
- * const user = await User.find(1);
394
- *
395
- * return Post
396
- * .byUser(user)
397
- * .isPublic()
398
- * .withEverything();
236
+ * const posts = await Post.byUser(user).isPublic().page(2);
399
237
  * ```
400
238
  *
401
- * Since scopes can be chained with built-in query methods, we can easily
402
- * paginate this collection.
403
- *
404
- * ```javascript
405
- * const user = await User.find(1);
406
- *
407
- * return Post
408
- * .byUser(user)
409
- * .isPublic()
410
- * .withEverything()
411
- * .page(1);
412
- * ```
239
+ * {@link Query.unscope} removes a scope from a query again.
413
240
  *
414
- * @property scopes
415
- * @type {Object}
416
- * @default {}
417
- * @static
418
- * @public
241
+ * A scope narrows only the queries it is called on, and knows nothing of
242
+ * the request. Calling `isPublic()` in a controller's `index` hides private
243
+ * posts from that listing alone: `show`, relationship linkage, `include` and
244
+ * the relationships of a write still reach them, and `unscope('isPublic')`
245
+ * undoes it. To hide records from every request in a namespace, use the
246
+ * scope in a controller visibility rule instead
247
+ * ({@link Controller.visibility}), which Lumen applies to every query it
248
+ * issues for the request and `unscope()` cannot remove.
419
249
  */
420
250
  static scopes: Record<string, unknown>;
421
251
  /**
422
- * An object where you declare hooks to execute at certain times in a model
423
- * instance's lifecycle.
424
- *
425
- * There are many lifecycle hooks that are executed through out a model
426
- * instance's lifetime. The have many use cases such as sanitization of
427
- * attributes, creating dependent relationships, hashing passwords, and much
428
- * more.
429
- *
430
- * ##### Execution Order
431
- *
432
- * When creating a record.
252
+ * Functions that run at points of a record's life, by name.
433
253
  *
434
- * 1. beforeValidation
435
- * 2. afterValidation
436
- * 3. beforeCreate
437
- * 4. beforeSave
438
- * 5. afterCreate
439
- * 6. afterSave
254
+ * | Creating | Updating | Deleting |
255
+ * |---|---|---|
256
+ * | `beforeValidation` | `beforeValidation` | `beforeDestroy` |
257
+ * | `afterValidation` | `afterValidation` | `afterDestroy` |
258
+ * | `beforeCreate` | `beforeUpdate` | |
259
+ * | `beforeSave` | `beforeSave` | |
260
+ * | `afterCreate` | `afterUpdate` | |
261
+ * | `afterSave` | `afterSave` | |
440
262
  *
441
- * When updating a record.
442
- *
443
- * 1. beforeValidation
444
- * 2. afterValidation
445
- * 3. beforeUpdate
446
- * 4. beforeSave
447
- * 5. afterUpdate
448
- * 6. afterSave
449
- *
450
- * When deleting a record.
451
- *
452
- * 1. beforeDestroy
453
- * 2. afterDestroy
454
- *
455
- * ##### Anatomy
456
- *
457
- * Hooks are async functions that are called with two arguments. The first
458
- * argument is the record that the hook applies to and the second argument is
459
- * the transaction object relevant to the method from which the hook was
460
- * called.
461
- *
462
- * The only time you will need to use the transaction object is if you are
463
- * creating, updating, or deleting different record(s) within the hook. Using
464
- * the transaction object when modifying the database in a hook ensures that
465
- * any modifications made within the hook will be rolled back if the function
466
- * that initiated the transaction fails.
263
+ * A hook is called with the record and the write's transaction,
264
+ * `(record, trx)`, and may be async. Everything it does through the record
265
+ * — reading a relationship, `update`, `save`, `destroy`, `reload` — runs in
266
+ * that transaction. Pass the transaction on for queries on other models,
267
+ * with `Model.transacting(trx)`. Then they see what the write has done so
268
+ * far, and are rolled back with it if a later step fails:
467
269
  *
468
270
  * ```javascript
469
- * import Notification from 'app/models/notification';
470
- *
471
271
  * class Comment extends Model {
472
- * static belongsTo = {
473
- * post: {
474
- * inverse: 'comments'
475
- * },
476
- * user: {
477
- * inverse: 'comments'
478
- * }
479
- * };
480
- *
481
272
  * static hooks = {
482
273
  * async afterCreate(comment, trx) {
483
- * let [post, commenter] = await Promise.all([
484
- * comment.post,
485
- * comment.user
486
- * ]);
487
- *
488
- * const commentee = await post.user;
274
+ * const post = await comment.post;
489
275
  *
490
- * post = post.title;
491
- * commenter = commenter.name;
492
- *
493
- * // Calling .transacting(trx) prevents the commentee from getting a
494
- * // notification if the comment fails to be persisted in the database.
495
- * await Notification
496
- * .transacting(trx)
497
- * .create({
498
- * user: commentee,
499
- * message: `${commenter} commented on your post "${post}"`
500
- * });
501
- * },
502
- *
503
- * async afterSave() {
504
- * // Good thing you called transacting in afterCreate.
505
- * throw new Error('Fatal Error');
276
+ * await Notification.transacting(trx).create({
277
+ * recipientId: post.userId,
278
+ * message: `New comment on "${post.title}"`
279
+ * });
506
280
  * }
507
281
  * };
508
282
  * }
509
283
  * ```
510
284
  *
511
- * @property hooks
512
- * @type {Object}
513
- * @default {}
514
- * @static
515
- * @public
285
+ * The record a hook receives is a proxy of the instance being written:
286
+ * attributes read and assign as usual, but compare records by
287
+ * {@link Model.getPrimaryKey}, not `===`.
516
288
  */
517
- static hooks: Model$Hooks;
289
+ static hooks: ModelHooks;
518
290
  /**
519
- * A reference to the application's logger.
520
- *
521
- * @property logger
522
- * @type {Logger}
523
- * @static
524
- * @public
291
+ * The application's logger.
525
292
  */
526
293
  static logger: Logger;
527
294
  /**
528
- * The name of the corresponding database table for the model.
529
- *
530
- * @property tableName
531
- * @type {String}
532
- * @static
533
- * @public
295
+ * The model's table: the pluralized, underscored class name (`BlogPost` →
296
+ * `blog_posts`), unless the model sets it.
534
297
  */
535
298
  static tableName: string;
536
299
  /**
537
- * The canonical name of the model.
538
- *
539
- * @property modelName
540
- * @type {String}
541
- * @static
542
- * @public
300
+ * The model's name, singular and dasherized (`blog-post`).
543
301
  */
544
302
  static modelName: string;
545
303
  /**
546
- * The name of the resource the model represents.
547
- *
548
- * @property resourceName
549
- * @type {String}
550
- * @static
551
- * @public
304
+ * The resource type the model is served as, plural and dasherized
305
+ * (`blog-posts`).
552
306
  */
553
307
  static resourceName: string;
554
308
  /**
555
- * The column name to use for a model's primary key.
556
- *
557
- * @property primaryKey
558
- * @type {String}
559
- * @default 'id'
560
- * @static
561
- * @public
309
+ * The primary key column.
562
310
  */
563
311
  static primaryKey: string;
564
- /**
565
- * @property table
566
- * @type {Function}
567
- * @static
568
- * @private
569
- */
312
+ /** @internal */
570
313
  static table: () => unknown;
571
- /**
572
- * @property store
573
- * @type {Database}
574
- * @static
575
- * @private
576
- */
314
+ /** @internal */
577
315
  static store: Database;
578
- /**
579
- * @property initialized
580
- * @type {Boolean}
581
- * @static
582
- * @private
583
- */
316
+ /** @internal */
584
317
  static initialized: boolean;
585
- /**
586
- * @property serializer
587
- * @type {Serializer}
588
- * @static
589
- * @private
590
- */
318
+ /** @internal */
591
319
  static serializer: Serializer<Model>;
592
- /**
593
- * @property attributes
594
- * @type {Object}
595
- * @static
596
- * @private
597
- */
320
+ /** @internal */
598
321
  static attributes: Record<string, unknown>;
599
- /**
600
- * @property attributeNames
601
- * @type {Array}
602
- * @static
603
- * @private
604
- */
322
+ /** @internal */
605
323
  static attributeNames: Array<string>;
324
+ /** @internal */
325
+ static relationships: Record<string, RelationshipOptions>;
326
+ /** @internal */
327
+ static relationshipNames: Array<string>;
606
328
  /**
607
- * @property relationships
608
- * @type {Object}
609
- * @static
610
- * @private
611
- */
612
- static relationships: Record<string, Relationship$opts>;
613
- /**
614
- * @property relationshipNames
615
- * @type {Array}
616
- * @static
617
- * @private
329
+ * Build a record without saving it; {@link Model.create} builds and saves
330
+ * one. `attrs` may hold attributes and relationships.
618
331
  */
619
- static relationshipNames: Array<string>;
620
332
  constructor(attrs?: Record<string, unknown>, initialize?: boolean);
621
333
  /**
622
- * Indicates if the model is new.
334
+ * Whether the record has never been saved.
623
335
  *
624
336
  * ```javascript
625
- * import Post from 'app/models/post';
337
+ * new Post({ title: 'Draft' }).isNew; // => true
626
338
  *
627
- * let post = new Post({
628
- * body: '',
629
- * title: 'New Post',
630
- * isPublic: false
631
- * });
632
- *
633
- * post.isNew;
634
- * // => true
635
- *
636
- * Post.create({
637
- * body: '',
638
- * title: 'New Post',
639
- * isPublic: false
640
- * }).then(post => {
641
- * post.isNew;
642
- * // => false;
643
- * });
339
+ * const post = await Post.create({ title: 'Draft' });
340
+ * post.isNew; // => false
644
341
  * ```
645
- *
646
- * @property isNew
647
- * @type {Boolean}
648
- * @public
649
342
  */
650
343
  get isNew(): boolean;
651
344
  /**
652
- * Indicates if the model is dirty.
345
+ * Whether the record has changes that aren't saved.
653
346
  *
654
347
  * ```javascript
655
- * import Post from 'app/models/post';
656
- *
657
- * Post
658
- * .find(1)
659
- * .then(post => {
660
- * post.isDirty;
661
- * // => false
348
+ * const post = await Post.find(1);
349
+ * post.isDirty; // => false
662
350
  *
663
- * post.isPublic = true;
351
+ * post.title = 'Renamed';
352
+ * post.isDirty; // => true
664
353
  *
665
- * post.isDirty;
666
- * // => true
667
- *
668
- * return post.save();
669
- * })
670
- * .then(post => {
671
- * post.isDirty;
672
- * // => false
673
- * });
354
+ * await post.save();
355
+ * post.isDirty; // => false
674
356
  * ```
675
- *
676
- * @property isDirty
677
- * @type {Boolean}
678
- * @public
679
357
  */
680
358
  get isDirty(): boolean;
681
359
  /**
682
- * Indicates if the model is persisted.
683
- *
684
- * ```javascript
685
- * import Post from 'app/models/post';
686
- *
687
- * Post
688
- * .find(1)
689
- * .then(post => {
690
- * post.persisted;
691
- * // => true
692
- *
693
- * post.isPublic = true;
694
- *
695
- * post.persisted;
696
- * // => false
697
- *
698
- * return post.save();
699
- * })
700
- * .then(post => {
701
- * post.persisted;
702
- * // => true
703
- * });
704
- * ```
705
- *
706
- * @property persisted
707
- * @type {Boolean}
708
- * @public
360
+ * Whether the record is saved and has no unsaved changes: neither
361
+ * {@link Model.isNew} nor {@link Model.isDirty}.
709
362
  */
710
363
  get persisted(): boolean;
711
364
  /**
712
- * @property dirtyAttributes
713
- * @type {Map}
714
- * @public
365
+ * The attributes changed since the record was last saved, with their new
366
+ * values.
367
+ *
368
+ * ```javascript
369
+ * if (user.dirtyAttributes.has('password')) {
370
+ * user.password = await hash(user.password);
371
+ * }
372
+ * ```
715
373
  */
716
374
  get dirtyAttributes(): Map<string, unknown>;
717
375
  /**
718
- * @property dirtyRelationships
719
- * @type {Map}
720
- * @public
376
+ * The relationships changed since the record was last saved, with their new
377
+ * values.
721
378
  */
722
379
  get dirtyRelationships(): Map<string, unknown>;
723
- /**
724
- * @property dirtyProperties
725
- * @type {Map}
726
- * @private
727
- */
380
+ /** @internal */
728
381
  get dirtyProperties(): Map<string, unknown>;
729
- /**
730
- * @property currentChangeSet
731
- * @type {ChangeSet}
732
- * @private
733
- */
382
+ /** @internal */
734
383
  get currentChangeSet(): ChangeSet;
735
- /**
736
- * @property currentChangeSet
737
- * @type {void | ChangeSet}
738
- * @private
739
- */
384
+ /** @internal */
740
385
  get persistedChangeSet(): ChangeSet | undefined;
741
386
  /**
742
- * Specify the transaction object to use for following save, update, or
743
- * destroy method calls.
744
- *
745
- * When you call a method like update or destroy, lumen will create a
746
- * transaction and wrap the internals of the method and other downstream
747
- * method calls like model hooks within. In some edge cases it can be more
748
- * useful to manually initiate the transaction. Bulk updating or destroying
749
- * are good examples of this. When you manually begin a transaction, you can
750
- * call this method to specify the transaction object that you would like to
751
- * use for subsequent mutation methods (save, update, destroy, etc.) so lumen
752
- * knows not to automatically begin a new transaction if/when a mutation
753
- * method is called.
387
+ * Bind the record to a transaction you started with
388
+ * {@link Model.transaction}: `save`, `update`, `destroy`, `reload` and
389
+ * relationship reads on the returned record run in `trx`, and so do the
390
+ * related records those reads return.
754
391
  *
755
392
  * ```javascript
756
- * const post = await Post.first();
757
- *
758
- * // This call to update uses the transaction that lumen will initiate.
759
- * await post.update({
760
- * // updates to post...
761
- * });
762
- *
763
- * await post.transaction(trx => {
764
- * // This call to update uses the transaction that we created with the
765
- * // call to the transaction method.
766
- * return post
767
- * .transacting(trx)
768
- * .update({
769
- * // updates to post...
770
- * });
393
+ * await Post.transaction(async trx => {
394
+ * await post.transacting(trx).update({ isPublic: true });
395
+ * await user.transacting(trx).update({ isActive: true });
771
396
  * });
772
397
  * ```
773
398
  *
774
- * @method transacting
775
- * @param {Transaction} transaction - A transaction object to forward to save,
776
- * update, or destroy method calls.
777
- * @return {Model} - Returns a proxied version of `this` that delagates the
778
- * transaction param to subsquent save, update, or destroy method calls.
779
- * @public
399
+ * Model hooks receive their record bound already.
400
+ *
401
+ * @param trx - The transaction.
402
+ * @returns A proxy of the record that uses `trx`.
780
403
  */
781
404
  transacting(trx: unknown): this;
782
405
  /**
783
- * Manually begin a new transaction.
406
+ * Run `fn` in a new transaction; the same as {@link Model.transaction} on
407
+ * the record's model.
784
408
  *
785
- * Most of the time, you don't need to start transactions yourself. However,
786
- * if you need to do something like implement bulk updating of related records
787
- * the transaction method can be useful.
788
- *
789
- * ```javascript
790
- * const post = await Post.first().include('user');
791
- * const user = await post.user;
792
- *
793
- * await post.transaction(trx => {
794
- * return Promise.all([
795
- * post.transacting(trx).update({
796
- * // updates to post...
797
- * }),
798
- * user.transacting(trx).update({
799
- * // updates to user...
800
- * })
801
- * ]);
802
- * });
803
- * ```
804
- *
805
- * @method transaction
806
- * @param {Function} fn - The function used for executing the tranasction.
807
- * This function is called with a new transaction object as it's only argument
808
- * and is expected to return a promise.
809
- * @return {Promise} Resolves with the resolved value of the fn param.
810
- * @public
409
+ * @param fn - Called with the transaction. It commits when the promise `fn`
410
+ * returns resolves, and rolls back when it rejects.
411
+ * @returns Resolves with what `fn` resolved with.
811
412
  */
812
413
  transaction<T>(fn: (...args: Array<unknown>) => Promise<T>): Promise<T>;
813
414
  /**
814
- * Persist any unsaved changes to the database.
415
+ * Save the changes made by assigning to the record.
815
416
  *
816
417
  * ```javascript
817
- * const post = await Post.first();
818
- *
819
- * console.log(post.title, post.isDirty);
820
- * // => 'New Post' false
821
- *
822
- * post.title = 'How to Save a Lumen Model';
823
- *
824
- * console.log(post.title, post.isDirty);
825
- * // => 'How to Update a Lumen Model' true
418
+ * const post = await Post.find(1);
826
419
  *
420
+ * post.title = 'Renamed';
827
421
  * await post.save();
828
- *
829
- * console.log(post.title, post.isDirty);
830
- * // => 'How to Save a Lumen Model' false
831
422
  * ```
832
423
  *
833
- * @method save
834
- * @return {Promise} Resolves with `this`.
835
- * @public
424
+ * Validations and the update hooks run, in a transaction of their own unless
425
+ * one is given.
426
+ *
427
+ * @param transaction - A transaction to run in, instead of a new one.
428
+ * @returns Resolves with the record; its `didPersist` is `false` when
429
+ * there was nothing to save.
836
430
  */
837
- save(transaction?: unknown): Promise<Transaction$ResultProxy<this, boolean>>;
431
+ save(transaction?: unknown): Promise<TransactionResult<this, boolean>>;
838
432
  /**
839
- * Assign values to the instance and persist any changes to the database.
433
+ * Assign `props` to the record and save it.
840
434
  *
841
435
  * ```javascript
842
- * const post = await Post.first();
436
+ * const post = await Post.find(1);
843
437
  *
844
- * console.log(post.title, post.isPublic, post.isDirty);
845
- * // => 'New Post' false false
846
- *
847
- * await post.update({
848
- * title: 'How to Update a Lumen Model',
849
- * isPublic: true
850
- * });
851
- *
852
- * console.log(post.title, post.isPublic, post.isDirty);
853
- * // => 'How to Update a Lumen Model' true false
438
+ * await post.update({ title: 'Renamed', isPublic: true });
854
439
  * ```
855
440
  *
856
- * @method update
857
- * @param {Object} properties - An object containing key, value pairs of the
858
- * attributes and/or relationships you would like to assign to the instance.
859
- * @return {Promise} Resolves with `this`.
860
- * @public
441
+ * Validations and the update hooks run, in a transaction of their own unless
442
+ * one is given.
443
+ *
444
+ * @param props - Attributes and relationships to assign.
445
+ * @param transaction - A transaction to run in, instead of a new one.
446
+ * @returns Resolves with the record; its `didPersist` is `false` when nothing
447
+ * changed.
861
448
  */
862
- update(props?: Record<string, unknown>, transaction?: unknown): Promise<Transaction$ResultProxy<this, boolean>>;
449
+ update(props?: Record<string, unknown>, transaction?: unknown): Promise<TransactionResult<this, boolean>>;
863
450
  /**
864
- * Permanently delete the instance from the database.
451
+ * Delete the record, running the destroy hooks, in a transaction of its own
452
+ * unless one is given.
865
453
  *
866
- * @method destroy
867
- * @return {Promise} Resolves with `this`.
868
- * @public
454
+ * @param transaction - A transaction to run in, instead of a new one.
455
+ * @returns Resolves with the record.
869
456
  */
870
- destroy(transaction?: unknown): Promise<Transaction$ResultProxy<this, true>>;
457
+ destroy(transaction?: unknown): Promise<TransactionResult<this, true>>;
871
458
  /**
872
- * Reload the record from the database.
459
+ * Fetch the record from the database again.
873
460
  *
874
- * @method reload
875
- * @return {Promise} Resolves with `this`.
876
- * @public
461
+ * @returns Resolves with a new instance of the record as stored (the record
462
+ * itself if it was never saved).
877
463
  */
878
464
  reload(): Promise<Model>;
879
465
  /**
880
- * Rollback attributes and relationships to the last known persisted set of
881
- * values.
466
+ * Discard the changes made since the record was last saved.
882
467
  *
883
- * @method rollback
884
- * @return {Model} Returns `this`.
885
- * @public
468
+ * @returns The record.
886
469
  */
887
470
  rollback(): this;
888
- /**
889
- * @method getAttributes
890
- * @param {String} [...keys] - The keys of the properties to return.
891
- * @return {Object} An object containing keys that were passed in as agruments
892
- * and their associated values.
893
- * @private
894
- */
471
+ /** @internal */
895
472
  getAttributes(...keys: Array<string>): Record<string, unknown>;
896
473
  /**
897
- * @method getPrimaryKey
898
- * @return {Number} The value of the primary key for the instance.
899
- * @private
474
+ * The record's primary key value. Compare records by it rather than by
475
+ * identity: the record a hook receives is a proxy of the one being written.
900
476
  */
901
477
  getPrimaryKey(): number;
902
478
  /**
903
- * Create and persist a new instance of the model.
479
+ * Build a record from `props` and save it.
480
+ *
481
+ * ```javascript
482
+ * const post = await Post.create({ title: 'Hello', user });
483
+ * ```
904
484
  *
905
- * @method create
906
- * @param {Object} properties - An object containing key, value pairs of the
907
- * attributes and/or relationships you would like to assign to the instance.
908
- * @return {Promise} Resolves with the newly created model.
909
- * @static
910
- * @public
485
+ * Validations and the create hooks run, in a transaction of their own unless
486
+ * one is given.
487
+ *
488
+ * @param props - Attributes and relationships of the new record.
489
+ * @param transaction - A transaction to run in, instead of a new one.
490
+ * @returns Resolves with the new record.
911
491
  */
912
- static create(props?: Record<string, unknown>, transaction?: unknown): Promise<Transaction$ResultProxy<Model, true>>;
492
+ static create(props?: Record<string, unknown>, transaction?: unknown): Promise<TransactionResult<Model, true>>;
913
493
  /**
914
- * Specify the transaction object to use for following save, update, or
915
- * destroy method calls.
916
- *
917
- * When you call a method like update or destroy, lumen will create a
918
- * transaction and wrap the internals of the method and other downstream
919
- * method calls like model hooks within. In some edge cases it can be more
920
- * useful to manually initiate the transaction. Bulk updating or destroying
921
- * are good examples of this. When you manually begin a transaction, you can
922
- * call this method to specify the transaction object that you would like to
923
- * use for calls to the static create method so lumen knows not to automatically
924
- * begin a new transaction if/when the static create method is called.
494
+ * Bind the model to a transaction: `create`, and every query started from
495
+ * the returned model — `find`, `where`, `first`, `count`, scopes and the
496
+ * rest, with the queries that load their included relationships — run in
497
+ * `trx`.
925
498
  *
926
499
  * ```javascript
927
- * // This call to create uses the transaction that lumen will initiate.
928
- * await Post.create();
929
- *
930
- * await Post.transaction(trx => {
931
- * // This call to create uses the transaction that we created with the
932
- * // call to the transaction method.
933
- * return Post
934
- * .transacting(trx)
935
- * .create();
500
+ * await Post.transaction(async trx => {
501
+ * const post = await Post.transacting(trx).create({ title: 'Hello' });
502
+ * await Comment.transacting(trx).create({ postId: post.id });
936
503
  * });
937
504
  * ```
938
505
  *
939
- * @method transacting
940
- * @param {Transaction} transaction - A transaction object to forward to
941
- * create method calls.
942
- * @return {Model} - Returns a proxied version of `this` that delagates the
943
- * transaction param to subsquent create method calls.
944
- * @static
945
- * @public
506
+ * A model hook reads through the transaction it is given, so it sees what the
507
+ * write has done so far, and doesn't wait for a second connection while the
508
+ * transaction holds one:
509
+ *
510
+ * ```javascript
511
+ * static hooks = {
512
+ * async afterCreate(comment, trx) {
513
+ * const post = await Post.transacting(trx).find(comment.postId);
514
+ * // …
515
+ * }
516
+ * };
517
+ * ```
518
+ *
519
+ * @param trx - The transaction.
520
+ * @returns A proxy of the model that uses `trx`.
946
521
  */
947
522
  static transacting(trx: unknown): ModelClass;
948
523
  /**
949
- * Manually begin a new transaction.
950
- *
951
- * Most of the time, you don't need to start transactions yourself. However,
952
- * the transaction method can be useful if you need to do something like
953
- * bulk creating records.
524
+ * Run `fn` in a new transaction. Every write runs in a transaction of its
525
+ * own; start one yourself to group several, and pass it on with
526
+ * `transacting`:
954
527
  *
955
528
  * ```javascript
956
- * await Post.transaction(trx => {
957
- * return Promise.all([
958
- * Post.transacting(trx).create({
959
- * // ...props
960
- * }),
961
- * Post.transacting(trx).create({
962
- * // ...props
963
- * })
964
- * ]);
529
+ * await Post.transaction(async trx => {
530
+ * await Post.transacting(trx).create({ title: 'One' });
531
+ * await Post.transacting(trx).create({ title: 'Two' });
965
532
  * });
966
533
  * ```
967
534
  *
968
- * @method transaction
969
- * @param {Function} fn - The function used for executing the tranasction.
970
- * This function is called with a new transaction object as it's only argument
971
- * and is expected to return a promise.
972
- * @return {Promise} Resolves with the resolved value of the fn param.
973
- * @static
974
- * @public
535
+ * @param fn - Called with the transaction. It commits when the promise `fn`
536
+ * returns resolves, and rolls back when it rejects.
537
+ * @returns Resolves with what `fn` resolved with.
975
538
  */
976
539
  static transaction<T>(fn: (...args: Array<unknown>) => Promise<T>): Promise<T>;
540
+ /**
541
+ * Every record. Starts a {@link Query}; see {@link Query.all}.
542
+ */
977
543
  static all(): Query<Array<Model>>;
544
+ /**
545
+ * The record with primary key `primaryKey`; rejects with a
546
+ * `RecordNotFoundError` (`404` through the API) if there is none. Starts a
547
+ * {@link Query}; see {@link Query.find}.
548
+ */
978
549
  static find(primaryKey: unknown): Query<Model>;
550
+ /**
551
+ * Page `num` of the records. Starts a {@link Query}; see {@link Query.page}.
552
+ */
979
553
  static page(num: number): Query<Array<Model>>;
554
+ /**
555
+ * At most `amount` records. Starts a {@link Query}; see {@link Query.limit}.
556
+ */
980
557
  static limit(amount: number): Query<Array<Model>>;
558
+ /**
559
+ * Skip `amount` records. Starts a {@link Query}; see {@link Query.offset}.
560
+ */
981
561
  static offset(amount: number): Query<Array<Model>>;
562
+ /**
563
+ * The number of records. Starts a {@link Query}; see {@link Query.count}.
564
+ */
982
565
  static count(): Query<number>;
566
+ /**
567
+ * The records sorted by `attr`. Starts a {@link Query}; see
568
+ * {@link Query.order}.
569
+ */
983
570
  static order(attr: string, direction?: string): Query<Array<Model>>;
571
+ /**
572
+ * The records matching `conditions`. Starts a {@link Query}; see
573
+ * {@link Query.where}.
574
+ */
984
575
  static where(conditions: Record<string, unknown>): Query<Array<Model>>;
576
+ /**
577
+ * The records with values within ranges. Starts a {@link Query}; see
578
+ * {@link Query.whereBetween}.
579
+ */
985
580
  static whereBetween(conditions: Record<string, unknown>): Query<Array<Model>>;
581
+ /**
582
+ * The records matching a raw SQL condition. Starts a {@link Query}; see
583
+ * {@link Query.whereRaw}.
584
+ */
986
585
  static whereRaw(query: string, bindings?: Array<unknown>): Query<Array<Model>>;
586
+ /**
587
+ * The records not matching `conditions`. Starts a {@link Query}; see
588
+ * {@link Query.not}.
589
+ */
987
590
  static not(conditions: Record<string, unknown>): Query<Array<Model>>;
591
+ /**
592
+ * The first record. Starts a {@link Query}; see {@link Query.first}.
593
+ */
988
594
  static first(): Query<Model>;
595
+ /**
596
+ * The last record. Starts a {@link Query}; see {@link Query.last}.
597
+ */
989
598
  static last(): Query<Model>;
599
+ /**
600
+ * Only these attributes. Starts a {@link Query}; see {@link Query.select}.
601
+ */
990
602
  static select(...params: Array<string>): Query<Array<Model>>;
603
+ /**
604
+ * Unique values of these attributes. Starts a {@link Query}; see
605
+ * {@link Query.distinct}.
606
+ */
991
607
  static distinct(...params: Array<string>): Query<Array<Model>>;
608
+ /**
609
+ * The records with these relationships loaded. Starts a {@link Query}; see
610
+ * {@link Query.include}.
611
+ */
992
612
  static include(...relationships: Array<string | Record<string, unknown>>): Query<Array<Model>>;
613
+ /**
614
+ * The records without these scopes. Starts a {@link Query}; see
615
+ * {@link Query.unscope}.
616
+ */
993
617
  static unscope(...scopes: Array<string>): Query<Array<Model>>;
994
618
  /**
995
- * Check if a model has a scope.
996
- *
997
- * @method hasScope
998
- * @param {String} name - The name of the scope to look for.
999
- * @return {Boolean}
1000
- * @static
1001
- * @public
619
+ * Whether the model declares the scope `name` in {@link Model.scopes}.
1002
620
  */
1003
621
  static hasScope(name: string): boolean;
1004
622
  /**
1005
- * Check if a value is an instance of a model.
1006
- *
1007
- * @method isInstance
1008
- * @param {any} value - The value in question.
1009
- * @return {Boolean}
1010
- * @static
1011
- * @public
623
+ * Whether `value` is a record of this model.
1012
624
  */
1013
625
  static isInstance(value: unknown): boolean;
1014
626
  /**
1015
627
  * Bind the model's connection to the database and get inferred data from the
1016
628
  * schema upon application boot.
1017
629
  *
1018
- * @method initialize
1019
- * @param {Database} store - A reference of the applications database
630
+ * @param store - A reference of the applications database
1020
631
  * instance.
1021
- * @param {Table} table - A function that returns a knex query builder bound
632
+ * @param table - A function that returns a knex query builder bound
1022
633
  * to the model's table name.
1023
- * @return {Promise} Resolves with the model class.
1024
- * @static
1025
- * @private
634
+ * @returns Resolves with the model class.
635
+ * @internal
1026
636
  */
1027
637
  static initialize(store: Database, table: () => unknown): Promise<ModelClass>;
1028
- /**
1029
- * @method columnFor
1030
- * @param {String} key - The respective attribute name of the column.
1031
- * @return {void | Object} An object containing metadata about the column if a
1032
- * match is found.
1033
- * @static
1034
- * @private
1035
- */
1036
- static columnFor(key: string): Database$column | undefined;
1037
- /**
1038
- * @method columnNameFor
1039
- * @param {String} key - The respective attribute name of the column.
1040
- * @return {void | String} The name of the column in the database if a match
1041
- * is found.
1042
- * @static
1043
- * @private
1044
- */
638
+ /** @internal */
639
+ static columnFor(key: string): DatabaseColumn | undefined;
640
+ /** @internal */
1045
641
  static columnNameFor(key: string): string | undefined;
1046
- /**
1047
- * @method relationshipFor
1048
- * @param {String} key - The name of the relationship to match against.
1049
- * @return {void | Object} An object containing relationship metadata if a
1050
- * match is found.
1051
- * @static
1052
- * @private
1053
- */
1054
- static relationshipFor(key: string): Relationship$opts | undefined;
642
+ /** @internal */
643
+ static relationshipFor(key: string): RelationshipOptions | undefined;
1055
644
  }
1056
645
  export default Model;
1057
- export type { Model$Hook, Model$Hooks } from './interfaces';
646
+ export type { ModelHook, ModelHooks } from './interfaces';