@ditojs/server 2.0.5 → 2.1.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 (53) hide show
  1. package/package.json +11 -13
  2. package/src/app/Application.js +226 -179
  3. package/src/app/Validator.js +53 -43
  4. package/src/cli/console.js +6 -4
  5. package/src/cli/db/createMigration.js +59 -30
  6. package/src/cli/db/migrate.js +6 -4
  7. package/src/cli/db/reset.js +8 -5
  8. package/src/cli/db/rollback.js +6 -4
  9. package/src/cli/db/seed.js +2 -1
  10. package/src/cli/index.js +1 -1
  11. package/src/controllers/AdminController.js +98 -84
  12. package/src/controllers/CollectionController.js +37 -30
  13. package/src/controllers/Controller.js +83 -43
  14. package/src/controllers/ControllerAction.js +27 -15
  15. package/src/controllers/ModelController.js +4 -1
  16. package/src/controllers/RelationController.js +19 -21
  17. package/src/controllers/UsersController.js +3 -4
  18. package/src/decorators/parameters.js +3 -1
  19. package/src/decorators/scope.js +1 -1
  20. package/src/errors/ControllerError.js +2 -1
  21. package/src/errors/DatabaseError.js +20 -11
  22. package/src/graph/DitoGraphProcessor.js +48 -40
  23. package/src/graph/expression.js +6 -8
  24. package/src/graph/graph.js +20 -11
  25. package/src/lib/EventEmitter.js +12 -12
  26. package/src/middleware/handleConnectMiddleware.js +16 -10
  27. package/src/middleware/handleError.js +6 -5
  28. package/src/middleware/handleSession.js +33 -29
  29. package/src/middleware/handleUser.js +2 -2
  30. package/src/middleware/index.js +1 -0
  31. package/src/middleware/logRequests.js +3 -3
  32. package/src/middleware/setupRequestStorage.js +14 -0
  33. package/src/mixins/AssetMixin.js +62 -58
  34. package/src/mixins/SessionMixin.js +13 -10
  35. package/src/mixins/TimeStampedMixin.js +33 -29
  36. package/src/mixins/UserMixin.js +130 -116
  37. package/src/models/Model.js +245 -194
  38. package/src/models/definitions/filters.js +14 -13
  39. package/src/query/QueryBuilder.js +252 -195
  40. package/src/query/QueryFilters.js +3 -3
  41. package/src/query/QueryParameters.js +2 -2
  42. package/src/query/Registry.js +8 -10
  43. package/src/schema/keywords/_validate.js +10 -8
  44. package/src/schema/properties.test.js +247 -206
  45. package/src/schema/relations.js +42 -20
  46. package/src/schema/relations.test.js +36 -19
  47. package/src/services/Service.js +8 -14
  48. package/src/storage/S3Storage.js +5 -3
  49. package/src/storage/Storage.js +16 -14
  50. package/src/utils/function.js +7 -4
  51. package/src/utils/function.test.js +30 -6
  52. package/src/utils/object.test.js +5 -1
  53. package/types/index.d.ts +244 -257
package/types/index.d.ts CHANGED
@@ -6,28 +6,27 @@
6
6
  // Export the entire Dito namespace.
7
7
 
8
8
  import { ObjectCannedACL, S3ClientConfig } from '@aws-sdk/client-s3'
9
- import { DateFormat } from '@dito/utils'
10
- import koaCors from '@koa/cors'
9
+ import { DateFormat } from '@ditojs/utils'
10
+ import { Options as KoaCorsOptions } from '@koa/cors'
11
11
  import * as Ajv from 'ajv/dist/2020.js'
12
+ import { AsyncLocalStorage } from 'async_hooks'
12
13
  import * as dbErrors from 'db-errors'
13
14
  import * as EventEmitter2 from 'eventemitter2'
14
15
  import helmet from 'helmet'
15
- import * as Knex from 'knex'
16
+ import { Knex } from 'knex'
16
17
  import * as Koa from 'koa'
17
- import koaBodyParser from 'koa-bodyparser'
18
- import koaCompress from 'koa-compress'
19
- import koaLogger from 'koa-logger'
20
- import mount from 'koa-mount'
21
- import koaPinoLogger from 'koa-pino-logger'
18
+ import { Options as KoaBodyParserOptions } from 'koa-bodyparser'
19
+ import { CompressOptions } from 'koa-compress'
20
+ import koaMount from 'koa-mount'
22
21
  import koaResponseTime from 'koa-response-time'
23
22
  import koaSession from 'koa-session'
24
23
  import multerS3 from 'multer-s3'
25
24
  import * as objection from 'objection'
26
25
  import { KnexSnakeCaseMappersFactory } from 'objection'
27
- import { Logger } from 'pino'
26
+ import { Logger as PinoLogger, LoggerOptions as PinoLoggerOptions } from 'pino'
27
+ import { PrettyOptions } from 'pino-pretty'
28
28
  import {
29
29
  Class,
30
- ConditionalExcept,
31
30
  ConditionalKeys,
32
31
  Constructor,
33
32
  SetOptional,
@@ -126,29 +125,29 @@ export type ApplicationConfig = {
126
125
  * @see https://github.com/helmetjs/helmet
127
126
  */
128
127
  helmet?: boolean | Parameters<typeof helmet>[0]
129
- logger?:
130
- | Parameters<typeof koaLogger>[0]
131
- | Parameters<typeof koaPinoLogger>[0]
128
+ logger?: {
129
+ prettyPrint: PrettyOptions
130
+ } & PinoLoggerOptions
132
131
  /**
133
132
  * Configure body parser.
134
133
  *
135
134
  * @see https://github.com/koajs/bodyparser#options
136
135
  */
137
- bodyParser?: koaBodyParser.Options
136
+ bodyParser?: KoaBodyParserOptions
138
137
  /**
139
138
  * Enable or configure Cross-Origin Resource Sharing (CORS)
140
139
  *
141
140
  * @defaultValue `true`
142
141
  * @see https://github.com/koajs/cors#corsoptions
143
142
  */
144
- cors?: boolean | koaCors.Options
143
+ cors?: boolean | KoaCorsOptions
145
144
  /**
146
145
  * Enable or configure server response compression
147
146
  *
148
147
  * @defaultValue `true`
149
148
  * @see https://github.com/koajs/compress#options
150
149
  */
151
- compress?: boolean | koaCompress.CompressOptions
150
+ compress?: boolean | CompressOptions
152
151
  /**
153
152
  * Enable ETag headers in server responses
154
153
  *
@@ -346,6 +345,11 @@ export interface ApplicationControllers {
346
345
 
347
346
  export type Models = Record<string, Class<Model>>
348
347
 
348
+ interface AsyncRequestLocals {
349
+ transaction: objection.Transaction
350
+ logger: PinoLogger
351
+ }
352
+
349
353
  export class Application<$Models extends Models = Models> {
350
354
  constructor(options: {
351
355
  config?: ApplicationConfig
@@ -382,8 +386,11 @@ export class Application<$Models extends Models = Models> {
382
386
  addControllers(controllers: ApplicationControllers, namespace?: string): void
383
387
  setupControllers(): Promise<void>
384
388
  getAdminViteConfig(config?: UserConfig): UserConfig
385
- logger: Logger
389
+ logger: PinoLogger
390
+ requestStorage: AsyncLocalStorage<AsyncRequestLocals>
391
+ requestLocals: AsyncRequestLocals
386
392
  }
393
+
387
394
  export interface Application
388
395
  extends Omit<
389
396
  Koa,
@@ -608,7 +615,8 @@ export type ModelHooks<$Model extends Model = Model> = {
608
615
  | 'find'
609
616
  | 'insert'
610
617
  | 'update'
611
- | 'delete'}`]?: ModelHookFunction<$Model>
618
+ | 'delete'
619
+ }`]?: ModelHookFunction<$Model>
612
620
  }
613
621
 
614
622
  export class Model extends objection.Model {
@@ -686,8 +694,6 @@ export class Model extends objection.Model {
686
694
  static clearWithScope: StaticQueryBuilderMethod<'clearWithScope'>
687
695
 
688
696
  static clear: StaticQueryBuilderMethod<'clear'>
689
- static pick: StaticQueryBuilderMethod<'pick'>
690
- static omit: StaticQueryBuilderMethod<'omit'>
691
697
  static select: StaticQueryBuilderMethod<'select'>
692
698
 
693
699
  static insert: StaticQueryBuilderMethod<'insert'>
@@ -716,26 +722,14 @@ export class Model extends objection.Model {
716
722
  static upsertDitoGraph: StaticQueryBuilderMethod<'upsertDitoGraph'>
717
723
  static updateDitoGraph: StaticQueryBuilderMethod<'updateDitoGraph'>
718
724
  static patchDitoGraph: StaticQueryBuilderMethod<'patchDitoGraph'>
719
- static insertDitoGraphAndFetch:
720
- StaticQueryBuilderMethod<'insertDitoGraphAndFetch'>
721
-
722
- static upsertDitoGraphAndFetch:
723
- StaticQueryBuilderMethod<'upsertDitoGraphAndFetch'>
724
-
725
- static updateDitoGraphAndFetch:
726
- StaticQueryBuilderMethod<'updateDitoGraphAndFetch'>
727
-
728
- static patchDitoGraphAndFetch:
729
- StaticQueryBuilderMethod<'patchDitoGraphAndFetch'>
730
-
731
- static upsertDitoGraphAndFetchById:
732
- StaticQueryBuilderMethod<'upsertDitoGraphAndFetchById'>
733
-
734
- static updateDitoGraphAndFetchById:
735
- StaticQueryBuilderMethod<'updateDitoGraphAndFetchById'>
736
725
 
737
- static patchDitoGraphAndFetchById:
738
- StaticQueryBuilderMethod<'patchDitoGraphAndFetchById'>
726
+ static insertDitoGraphAndFetch: StaticQueryBuilderMethod<'insertDitoGraphAndFetch'>
727
+ static upsertDitoGraphAndFetch: StaticQueryBuilderMethod<'upsertDitoGraphAndFetch'>
728
+ static updateDitoGraphAndFetch: StaticQueryBuilderMethod<'updateDitoGraphAndFetch'>
729
+ static patchDitoGraphAndFetch: StaticQueryBuilderMethod<'patchDitoGraphAndFetch'>
730
+ static upsertDitoGraphAndFetchById: StaticQueryBuilderMethod<'upsertDitoGraphAndFetchById'>
731
+ static updateDitoGraphAndFetchById: StaticQueryBuilderMethod<'updateDitoGraphAndFetchById'>
732
+ static patchDitoGraphAndFetchById: StaticQueryBuilderMethod<'patchDitoGraphAndFetchById'>
739
733
 
740
734
  static where: StaticQueryBuilderMethod<'where'>
741
735
  static whereNot: StaticQueryBuilderMethod<'whereNot'>
@@ -753,7 +747,7 @@ export class Model extends objection.Model {
753
747
  static whereNotColumn: StaticQueryBuilderMethod<'whereNotColumn'>
754
748
  static whereComposite: StaticQueryBuilderMethod<'whereComposite'>
755
749
  static whereInComposite: StaticQueryBuilderMethod<'whereInComposite'>
756
- // whereNotInComposite: QueryBuilder<Model>['whereNotInComposite']
750
+ static whereNotInComposite: StaticQueryBuilderMethod<'whereInComposite'> // TODO: `whereNotInComposite`
757
751
  static whereJsonHasAny: StaticQueryBuilderMethod<'whereJsonHasAny'>
758
752
  static whereJsonHasAll: StaticQueryBuilderMethod<'whereJsonHasAll'>
759
753
  static whereJsonIsArray: StaticQueryBuilderMethod<'whereJsonIsArray'>
@@ -777,17 +771,6 @@ export class Model extends objection.Model {
777
771
  static havingRaw: StaticQueryBuilderMethod<'havingRaw'>
778
772
  static havingWrapped: StaticQueryBuilderMethod<'havingWrapped'>
779
773
 
780
- // deprecated methods that are still supported at the moment.
781
- // TODO: Remove once we move to Objection 3.0
782
-
783
- static eager: StaticQueryBuilderMethod<'eager'>
784
- static joinEager: StaticQueryBuilderMethod<'joinEager'>
785
- static naiveEager: StaticQueryBuilderMethod<'naiveEager'>
786
- static mergeEager: StaticQueryBuilderMethod<'mergeEager'>
787
- static mergeJoinEager: StaticQueryBuilderMethod<'mergeJoinEager'>
788
- static mergeNaiveEager: StaticQueryBuilderMethod<'mergeNaiveEager'>
789
- static clearEager: StaticQueryBuilderMethod<'clearEager'>
790
-
791
774
  // static scope: QueryBuilder<Model>['scope']
792
775
  // static mergeScope: QueryBuilder<Model>['mergeScope']
793
776
  // static clearScope: QueryBuilder<Model>['clearScope']
@@ -896,7 +879,7 @@ export class Controller {
896
879
  * middleware.
897
880
  * @overridable
898
881
  */
899
- compose(): Parameters<typeof mount>[1]
882
+ compose(): Parameters<typeof koaMount>[1]
900
883
  /** To be overridden by sub-classes. */
901
884
  getPath(type: string, path: string): string
902
885
  getUrl(type: string, path: string): string
@@ -930,10 +913,10 @@ export type ControllerActionHandler<
930
913
  $Controller extends Controller = Controller
931
914
  > = (this: $Controller, ctx: KoaContext, ...args: any[]) => any
932
915
 
933
- export type ExtractModelProperties<$Model> = {
934
- [$Key in SelectModelPropertyKeys<$Model>]: $Model[$Key] extends Model
935
- ? ExtractModelProperties<$Model[$Key]>
936
- : $Model[$Key]
916
+ export type ExtractModelProperties<$Model extends Model = Model> = {
917
+ [K in SelectModelPropertyKeys<$Model>]: $Model[K] extends Model
918
+ ? ExtractModelProperties<$Model[K]>
919
+ : $Model[K]
937
920
  }
938
921
 
939
922
  export type Extends<$A, $B> = $A extends $B ? 1 : 0
@@ -945,8 +928,8 @@ export type SelectModelPropertyKeys<$Model extends Model> = {
945
928
  | `$${string}`
946
929
  ? never
947
930
  : $Model[K] extends Function
948
- ? never
949
- : K
931
+ ? never
932
+ : K
950
933
  }[keyof $Model]
951
934
 
952
935
  export type Authorize =
@@ -1112,10 +1095,18 @@ type ModelControllerHookType = 'collection' | 'member'
1112
1095
  type ModelControllerHookKeys<
1113
1096
  $Keys extends string,
1114
1097
  $ModelControllerHookType extends string
1115
- > = `${'before' | 'after' | '*'}:${$ModelControllerHookType | '*'}:${
1098
+ > = `${
1099
+ | 'before'
1100
+ | 'after'
1101
+ | '*'
1102
+ }:${
1103
+ | $ModelControllerHookType
1104
+ | '*'
1105
+ }:${
1116
1106
  | Exclude<$Keys, 'allow'>
1117
1107
  | ControllerActionName
1118
- | '*'}`
1108
+ | '*'
1109
+ }`
1119
1110
  type ModelControllerHook<
1120
1111
  $ModelController extends ModelController = ModelController
1121
1112
  > = (
@@ -1143,11 +1134,16 @@ type HookKeysFromController<$ModelController extends ModelController> =
1143
1134
 
1144
1135
  type HandlerFromHookKey<
1145
1136
  $ModelController extends ModelController,
1146
- $Key extends HookKeysFromController<$ModelController>
1147
- > = $Key extends `${'before' | 'after' | '*'}:${
1137
+ K extends HookKeysFromController<$ModelController>
1138
+ > = K extends `${
1139
+ | 'before'
1140
+ | 'after'
1141
+ | '*'
1142
+ }:${
1148
1143
  | 'collection'
1149
1144
  | 'member'
1150
- | '*'}:${string}`
1145
+ | '*'
1146
+ }:${string}`
1151
1147
  ? (this: $ModelController, ctx: KoaContext, ...args: any[]) => any
1152
1148
  : never
1153
1149
 
@@ -1441,12 +1437,13 @@ export class Service {
1441
1437
  * @overridable
1442
1438
  */
1443
1439
  initialize(): Promise<void>
1444
- /* @overridable */
1440
+ /** @overridable */
1445
1441
  start(): Promise<void>
1446
- /* @overridable */
1442
+ /** @overridable */
1447
1443
  stop(): Promise<void>
1448
- get logger(): Logger
1449
- getLogger(ctx: KoaContext): Logger
1444
+ get logger(): PinoLogger
1445
+ /** @deprecated Use `instance.logger` instead. */
1446
+ getLogger(ctx: KoaContext): PinoLogger
1450
1447
  }
1451
1448
  export type Services = Record<string, Class<Service> | Service>
1452
1449
 
@@ -1506,7 +1503,9 @@ export class QueryBuilder<
1506
1503
  query: QueryParameterOptions,
1507
1504
  allowParam?:
1508
1505
  | QueryParameterOptionKey[]
1509
- | { [key in keyof QueryParameterOptionKey]: boolean }
1506
+ | {
1507
+ [key in keyof QueryParameterOptionKey]: boolean
1508
+ }
1510
1509
  ) => this
1511
1510
 
1512
1511
  patchById: (id: Id, data: PartialModelObject<M>) => this
@@ -1581,10 +1580,10 @@ export type PartialModelObject<T extends Model> = {
1581
1580
  > extends Model
1582
1581
  ? T[K]
1583
1582
  : objection.Defined<T[K]> extends Array<infer I>
1584
- ? I extends Model
1585
- ? I[]
1583
+ ? I extends Model
1584
+ ? I[]
1585
+ : objection.Expression<T[K]>
1586
1586
  : objection.Expression<T[K]>
1587
- : objection.Expression<T[K]>
1588
1587
  }
1589
1588
 
1590
1589
  export type PartialDitoModelGraph<M extends Partial<Model>> = {
@@ -1593,10 +1592,10 @@ export type PartialDitoModelGraph<M extends Partial<Model>> = {
1593
1592
  > extends Model
1594
1593
  ? PartialDitoModelGraph<M[K]>
1595
1594
  : objection.Defined<M[K]> extends Array<infer I>
1596
- ? I extends Partial<Model>
1597
- ? PartialDitoModelGraph<I>[]
1595
+ ? I extends Partial<Model>
1596
+ ? PartialDitoModelGraph<I>[]
1597
+ : M[K]
1598
1598
  : M[K]
1599
- : M[K]
1600
1599
  }
1601
1600
 
1602
1601
  /* ------------------------------ Start Errors ----------------------------- */
@@ -1673,86 +1672,74 @@ type AssetFileObject = {
1673
1672
  height: number
1674
1673
  }
1675
1674
 
1676
- export class AssetModel extends TimeStampedModel {
1677
- key: string
1678
- file: AssetFileObject
1679
- storage: string
1680
- count: number
1681
- }
1682
-
1683
- export const AssetMixin: <T extends Constructor>(
1675
+ export const AssetMixin: <T extends Constructor<{}>>(
1684
1676
  target: T
1685
- ) => Constructor<
1686
- InstanceType<T> & {
1677
+ ) => T &
1678
+ Constructor<{
1687
1679
  key: string
1688
1680
  file: AssetFileObject
1689
1681
  storage: string
1690
1682
  count: number
1691
- }
1692
- >
1683
+ }>
1693
1684
 
1694
- export class TimeStampedModel extends Model {
1695
- createdAt: Date
1696
- updatedAt: Date
1697
- }
1685
+ export const AssetModel: ReturnType<typeof AssetMixin<typeof Model>>
1698
1686
 
1699
- export const TimeStampedMixin: <T extends Constructor>(
1687
+ export const TimeStampedMixin: <T extends Constructor<{}>>(
1700
1688
  target: T
1701
- ) => Constructor<InstanceType<T> & {
1702
- createdAt: Date
1703
- updatedAt: Date
1704
- }>
1705
-
1706
- export class UserModel extends Model {
1707
- static options?: {
1708
- usernameProperty?: string
1709
- passwordProperty?: string
1710
- /**
1711
- * This option can be used to specify (eager) scopes to be applied when the
1712
- * user is deserialized from the session.
1713
- */
1714
- sessionScope?: OrArrayOf<string>
1715
- }
1689
+ ) => T &
1690
+ Constructor<{
1691
+ createdAt: Date
1692
+ updatedAt: Date
1693
+ }>
1716
1694
 
1717
- username: string
1718
- password: string
1719
- hash: string
1720
- lastLogin?: Date
1695
+ export const TimeStampedModel: ReturnType<typeof TimeStampedMixin<typeof Model>>
1721
1696
 
1722
- $verifyPassword(password: string): Promise<boolean>
1697
+ export const SessionMixin: <T extends Constructor<{}>>(
1698
+ target: T
1699
+ ) => T &
1700
+ Constructor<{
1701
+ id: string
1702
+ value: { [key: string]: any }
1703
+ }>
1723
1704
 
1724
- $hasRole(...roles: string[]): boolean
1705
+ export const SessionModel: ReturnType<typeof SessionMixin<typeof Model>>
1725
1706
 
1726
- $hasOwner(owner: UserModel): boolean
1707
+ export const UserMixin: <T extends Constructor<{}>>(
1708
+ target: T
1709
+ ) => T &
1710
+ Constructor<{
1711
+ username: string
1712
+ password: string
1713
+ hash: string
1714
+ lastLogin?: Date
1727
1715
 
1728
- $isLoggedIn(ctx: KoaContext): boolean
1716
+ $verifyPassword(password: string): Promise<boolean>
1729
1717
 
1730
- // TODO: type options
1731
- static login(ctx: KoaContext, options: any): Promise<void>
1718
+ $hasRole(...roles: string[]): boolean
1732
1719
 
1733
- static sessionQuery(trx: Knex.Transaction): QueryBuilder<UserModel>
1734
- }
1720
+ $hasOwner(owner: InstanceType<typeof UserModel>): boolean
1735
1721
 
1736
- export class SessionModel extends Model {
1737
- id: string
1738
- value: { [key: string]: any }
1739
- }
1722
+ $isLoggedIn(ctx: KoaContext): boolean
1723
+ }> & {
1724
+ options?: {
1725
+ usernameProperty?: string
1726
+ passwordProperty?: string
1727
+ /**
1728
+ * This option can be used to specify (eager) scopes to be applied when
1729
+ * the user is deserialized from the session.
1730
+ */
1731
+ sessionScope?: OrArrayOf<string>
1732
+ }
1740
1733
 
1741
- export const SessionMixin: <T extends Constructor>(
1742
- target: T
1743
- ) => Constructor<InstanceType<T> & {
1744
- id: string
1745
- value: { [key: string]: any }
1746
- }>
1734
+ // TODO: type options
1735
+ login(ctx: KoaContext, options: any): Promise<void>
1747
1736
 
1748
- export const UserMixin: <T extends Constructor>(
1749
- target: T
1750
- ) => Constructor<
1751
- InstanceType<T> & {
1752
- id: string
1753
- value: { [key: string]: any }
1737
+ sessionQuery(
1738
+ trx: Knex.Transaction
1739
+ ): QueryBuilder<InstanceType<typeof UserModel>>
1754
1740
  }
1755
- >
1741
+
1742
+ export const UserModel: ReturnType<typeof UserMixin<typeof Model>>
1756
1743
 
1757
1744
  /**
1758
1745
  * Apply the action mixin to a controller action, in order to determine which
@@ -1868,25 +1855,16 @@ type ModelFromModelController<$ModelController extends ModelController> =
1868
1855
  InstanceType<Exclude<$ModelController['modelClass'], undefined>>
1869
1856
 
1870
1857
  export type SelectModelProperties<T> = {
1871
- [$Key in SelectModelKeys<T>]: T[$Key] extends Model
1872
- ? SelectModelProperties<T[$Key]>
1873
- : T[$Key]
1858
+ [K in SelectModelKeys<T>]: T[K] extends Model
1859
+ ? SelectModelProperties<T[K]>
1860
+ : T[K]
1874
1861
  }
1875
1862
 
1876
- // https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
1877
- type AnyGate<
1878
- $CheckType,
1879
- $TypeWhenNotAny,
1880
- $TypeWhenAny = $CheckType
1881
- > = 0 extends 1 & $CheckType ? $TypeWhenAny : $TypeWhenNotAny
1882
-
1883
- export type SelectModelKeys<T> = AnyGate<
1884
- T,
1885
- Exclude<
1886
- keyof ConditionalExcept<T, Function>,
1887
- `$${string}` | 'QueryBuilderType' | 'foreignKeyId'
1888
- >,
1889
- string
1863
+ export type SelectModelKeys<T> = Exclude<
1864
+ objection.NonFunctionPropertyNames<T>,
1865
+ | 'QueryBuilderType' //
1866
+ | 'foreignKeyId'
1867
+ | `$${string}`
1890
1868
  >
1891
1869
 
1892
1870
  /* ---------------------- Extended from Ajv JSON Schema --------------------- */
@@ -2001,11 +1979,10 @@ interface StringKeywords {
2001
1979
  | 'timestamp'
2002
1980
  >
2003
1981
  }
2004
- declare type UncheckedJSONSchemaType<
2005
- T,
2006
- IsPartial extends boolean
2007
- > = // these two unions allow arbitrary unions of types
2008
- (| {
1982
+
1983
+ // The first two unions allow arbitrary unions of types
1984
+ declare type UncheckedJSONSchemaType<T, IsPartial extends boolean> = (
1985
+ | {
2009
1986
  anyOf: readonly UncheckedJSONSchemaType<T, IsPartial>[]
2010
1987
  }
2011
1988
  | {
@@ -2015,118 +1992,127 @@ declare type UncheckedJSONSchemaType<
2015
1992
  type: readonly (T extends number
2016
1993
  ? JSONType<'number' | 'integer', IsPartial>
2017
1994
  : T extends string
2018
- ? JSONType<'string', IsPartial>
2019
- : T extends boolean
2020
- ? JSONType<'boolean', IsPartial>
2021
- : never)[]
1995
+ ? JSONType<'string', IsPartial>
1996
+ : T extends boolean
1997
+ ? JSONType<'boolean', IsPartial>
1998
+ : never)[]
2022
1999
  } & UnionToIntersection<
2023
2000
  T extends number
2024
2001
  ? NumberKeywords
2025
2002
  : T extends string
2026
- ? StringKeywords
2027
- : T extends boolean
2028
- ? {}
2029
- : never
2003
+ ? StringKeywords
2004
+ : T extends boolean
2005
+ ? {}
2006
+ : never
2030
2007
  >)
2031
2008
  | ((T extends number
2032
2009
  ? {
2033
2010
  type: JSONType<'number' | 'integer', IsPartial>
2034
2011
  } & NumberKeywords
2035
2012
  : T extends string
2036
- ? {
2037
- type: JSONType<
2038
- 'string' | 'text' | 'date' | 'datetime' | 'timestamp',
2039
- IsPartial
2040
- >
2041
- } & StringKeywords
2042
- : T extends Date
2043
- ? {
2044
- type: JSONType<'date' | 'datetime' | 'timestamp', IsPartial>
2045
- }
2046
- : T extends boolean
2047
- ? {
2048
- type: JSONType<'boolean', IsPartial>
2049
- }
2050
- : T extends readonly [any, ...any[]]
2051
- ? {
2052
- type: JSONType<'array', IsPartial>
2053
- items: {
2054
- readonly [K in keyof T]-?: UncheckedJSONSchemaType<T[K], false> &
2055
- Nullable<T[K]>
2056
- } & {
2057
- length: T['length']
2058
- }
2059
- minItems: T['length']
2060
- } & (
2061
- | {
2062
- maxItems: T['length']
2063
- }
2064
- | {
2065
- additionalItems: false
2066
- }
2067
- )
2068
- : T extends readonly any[]
2069
- ? {
2070
- type: JSONType<'array', IsPartial>
2071
- items: UncheckedJSONSchemaType<T[0], false>
2072
- contains?: UncheckedPartialSchema<T[0]>
2073
- minItems?: number
2074
- maxItems?: number
2075
- minContains?: number
2076
- maxContains?: number
2077
- uniqueItems?: true
2078
- additionalItems?: never
2079
- }
2080
- : T extends Record<string, any>
2081
- ? {
2082
- type: JSONType<'object', IsPartial>
2083
- additionalProperties?:
2084
- | boolean
2085
- | UncheckedJSONSchemaType<T[string], false>
2086
- unevaluatedProperties?:
2087
- | boolean
2088
- | UncheckedJSONSchemaType<T[string], false>
2089
- properties?: IsPartial extends true
2090
- ? Partial<UncheckedPropertiesSchema<T>>
2091
- : UncheckedPropertiesSchema<T>
2092
- patternProperties?: Record<
2093
- string,
2094
- UncheckedJSONSchemaType<T[string], false>
2095
- >
2096
- propertyNames?: Omit<
2097
- UncheckedJSONSchemaType<string, false>,
2098
- 'type'
2099
- > & {
2100
- type?: 'string'
2101
- }
2102
- dependencies?: {
2103
- [K in keyof T]?: Readonly<(keyof T)[]> | UncheckedPartialSchema<T>
2104
- }
2105
- dependentRequired?: {
2106
- [K in keyof T]?: Readonly<(keyof T)[]>
2107
- }
2108
- dependentSchemas?: {
2109
- [K in keyof T]?: UncheckedPartialSchema<T>
2110
- }
2111
- minProperties?: number
2112
- maxProperties?: number
2113
- } & (IsPartial extends true
2114
- ? {
2115
- required: Readonly<(keyof T)[] | boolean>
2116
- }
2117
- : [UncheckedRequiredMembers<T>] extends [never]
2013
+ ? {
2014
+ type: JSONType<
2015
+ 'string' | 'text' | 'date' | 'datetime' | 'timestamp',
2016
+ IsPartial
2017
+ >
2018
+ } & StringKeywords
2019
+ : T extends Date
2118
2020
  ? {
2119
- required?: Readonly<UncheckedRequiredMembers<T>[]> | boolean
2021
+ type: JSONType<'date' | 'datetime' | 'timestamp', IsPartial>
2120
2022
  }
2121
- : {
2122
- required: Readonly<UncheckedRequiredMembers<T>[]> | boolean
2123
- })
2124
- : T extends null
2125
- ? {
2126
- type: JSONType<'null', IsPartial>
2127
- nullable: true
2128
- }
2129
- : never) & {
2023
+ : T extends boolean
2024
+ ? {
2025
+ type: JSONType<'boolean', IsPartial>
2026
+ }
2027
+ : T extends readonly [any, ...any[]]
2028
+ ? {
2029
+ type: JSONType<'array', IsPartial>
2030
+ items: {
2031
+ readonly [K in keyof T]-?: UncheckedJSONSchemaType<
2032
+ T[K],
2033
+ false
2034
+ > &
2035
+ Nullable<T[K]>
2036
+ } & {
2037
+ length: T['length']
2038
+ }
2039
+ minItems: T['length']
2040
+ } & (
2041
+ | {
2042
+ maxItems: T['length']
2043
+ }
2044
+ | {
2045
+ additionalItems: false
2046
+ }
2047
+ )
2048
+ : T extends readonly any[]
2049
+ ? {
2050
+ type: JSONType<'array', IsPartial>
2051
+ items: UncheckedJSONSchemaType<T[0], false>
2052
+ contains?: UncheckedPartialSchema<T[0]>
2053
+ minItems?: number
2054
+ maxItems?: number
2055
+ minContains?: number
2056
+ maxContains?: number
2057
+ uniqueItems?: true
2058
+ additionalItems?: never
2059
+ }
2060
+ : T extends Record<string, any>
2061
+ ? {
2062
+ type: JSONType<'object', IsPartial>
2063
+ additionalProperties?:
2064
+ | boolean
2065
+ | UncheckedJSONSchemaType<T[string], false>
2066
+ unevaluatedProperties?:
2067
+ | boolean
2068
+ | UncheckedJSONSchemaType<T[string], false>
2069
+ properties?: IsPartial extends true
2070
+ ? Partial<UncheckedPropertiesSchema<T>>
2071
+ : UncheckedPropertiesSchema<T>
2072
+ patternProperties?: Record<
2073
+ string,
2074
+ UncheckedJSONSchemaType<T[string], false>
2075
+ >
2076
+ propertyNames?: Omit<
2077
+ UncheckedJSONSchemaType<string, false>,
2078
+ 'type'
2079
+ > & {
2080
+ type?: 'string'
2081
+ }
2082
+ dependencies?: {
2083
+ [K in keyof T]?:
2084
+ | Readonly<(keyof T)[]>
2085
+ | UncheckedPartialSchema<T>
2086
+ }
2087
+ dependentRequired?: {
2088
+ [K in keyof T]?: Readonly<(keyof T)[]>
2089
+ }
2090
+ dependentSchemas?: {
2091
+ [K in keyof T]?: UncheckedPartialSchema<T>
2092
+ }
2093
+ minProperties?: number
2094
+ maxProperties?: number
2095
+ } & (IsPartial extends true
2096
+ ? {
2097
+ required: Readonly<(keyof T)[] | boolean>
2098
+ }
2099
+ : [UncheckedRequiredMembers<T>] extends [never]
2100
+ ? {
2101
+ required?:
2102
+ | Readonly<UncheckedRequiredMembers<T>[]>
2103
+ | boolean
2104
+ }
2105
+ : {
2106
+ required:
2107
+ | Readonly<UncheckedRequiredMembers<T>[]>
2108
+ | boolean
2109
+ })
2110
+ : T extends null
2111
+ ? {
2112
+ type: JSONType<'null', IsPartial>
2113
+ nullable: true
2114
+ }
2115
+ : never) & {
2130
2116
  allOf?: Readonly<UncheckedPartialSchema<T>[]>
2131
2117
  anyOf?: Readonly<UncheckedPartialSchema<T>[]>
2132
2118
  oneOf?: Readonly<UncheckedPartialSchema<T>[]>
@@ -2142,6 +2128,7 @@ declare type UncheckedJSONSchemaType<
2142
2128
  $defs?: Record<string, UncheckedJSONSchemaType<Known, true>>
2143
2129
  definitions?: Record<string, UncheckedJSONSchemaType<Known, true>>
2144
2130
  }
2131
+
2145
2132
  declare type JSONSchemaType<T> = StrictNullChecksWrapper<
2146
2133
  'JSONSchemaType',
2147
2134
  UncheckedJSONSchemaType<T, false>