@bakery-framework/orm 2.2.0 → 2.2.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bakery-framework/orm",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "Bakery database layer: adapters, query builder, schema sync and backup.",
5
5
  "keywords": [
6
6
  "bakery",
@@ -56,6 +56,6 @@
56
56
  "bun": ">=1.4.0"
57
57
  },
58
58
  "dependencies": {
59
- "@bakery-framework/core": "^2.2.0"
59
+ "@bakery-framework/core": "^2.2.2"
60
60
  }
61
61
  }
@@ -21,6 +21,50 @@ export function isArrayValue(value: unknown): value is ArrayValue {
21
21
  return value instanceof ArrayValue
22
22
  }
23
23
 
24
+ declare const PG_ARRAY: unique symbol
25
+
26
+ /**
27
+ * The row type of a `Field.Array` column: an array, marked as a Postgres
28
+ * array so the write types can tell it from an array of another kind (a
29
+ * `jsonb` column typed `number[]`, which takes a plain array as JSON).
30
+ *
31
+ * The mark exists only in the types, and it is optional, so a plain array is
32
+ * a `PgArray` as it is: a read, a row built by hand and a test's
33
+ * `toEqual(['a'])` type as they would against `T[]`. A required mark broke
34
+ * all three. `Writable` reads the mark by its key rather than by
35
+ * assignability, since every plain array is assignable to an optional mark.
36
+ */
37
+ export type PgArray<T> = T[] & { readonly [PG_ARRAY]?: T }
38
+
39
+ /**
40
+ * What a write to a column of row type `V` accepts. A Postgres array column
41
+ * takes `DB.array()` of its elements and nothing else, since Bun cannot bind
42
+ * a plain array to one (see `ArrayValue`). Every other column takes its row
43
+ * type, `any` included: an unregistered schema stays permissive.
44
+ */
45
+ export type Writable<V> = 0 extends 1 & V
46
+ ? V
47
+ : V extends readonly (infer E)[]
48
+ ? typeof PG_ARRAY extends keyof V
49
+ ? ArrayValue<E>
50
+ : V
51
+ : V
52
+
53
+ /** A row's columns as a write accepts them. */
54
+ export type WritableRow<R> = { [K in keyof R]: Writable<R[K]> }
55
+
56
+ /**
57
+ * What an `INSERT` accepts for a row of type `Row`: its columns as a write
58
+ * takes them, the `Optional` ones optional. The one definition behind both
59
+ * `Mutation.InsertSchema` (a schema registered by declaration merging) and
60
+ * `InsertOf` (a `table()` value), so the two cannot disagree.
61
+ */
62
+ export type InsertRecord<Row, Optional extends keyof Row> = Omit<
63
+ WritableRow<Row>,
64
+ Optional
65
+ > &
66
+ Partial<Pick<WritableRow<Row>, Optional>>
67
+
24
68
  /**
25
69
  * The text of a Postgres array literal for `values`: `{"a","b c",NULL}`.
26
70
  *
package/src/define.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { InsertRecord } from './array-value'
1
2
  import type {
2
3
  ExtractOptionals,
3
4
  ExtractTableTypes,
@@ -368,13 +369,7 @@ export type RowOf<T extends TableRef> = ExtractTableTypes<
368
369
  * export type NewUser = InsertOf<typeof users>
369
370
  * // ^ { name: string; id?: number; createdAt?: number }
370
371
  */
371
- export type InsertOf<T extends TableRef> = Omit<
372
+ export type InsertOf<T extends TableRef> = InsertRecord<
372
373
  RowOf<T>,
373
374
  ExtractOptionals<{ t: T['__columns'] }, 't'> & keyof RowOf<T>
374
- > &
375
- Partial<
376
- Pick<
377
- RowOf<T>,
378
- ExtractOptionals<{ t: T['__columns'] }, 't'> & keyof RowOf<T>
379
- >
380
- >
375
+ >
package/src/field.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { throws } from '@bakery-framework/core/utils/common'
2
+ import type { PgArray } from './array-value'
2
3
  import type { DataTypes, TableDef } from './schema-util'
3
4
  import type * as SyncTypes from './sync/types'
4
5
 
@@ -382,15 +383,17 @@ export const Field = {
382
383
  if (options.nullable) def.nullable = true
383
384
  return def
384
385
  }) as {
385
- <E extends ArrayElement>(element: E): TableDef<ElementOf<E>[], false, false>
386
+ <E extends ArrayElement>(
387
+ element: E,
388
+ ): TableDef<PgArray<ElementOf<E>>, false, false>
386
389
  <E extends ArrayElement>(
387
390
  element: E,
388
391
  options: { optional: true },
389
- ): TableDef<ElementOf<E>[], false, true>
392
+ ): TableDef<PgArray<ElementOf<E>>, false, true>
390
393
  <E extends ArrayElement>(
391
394
  element: E,
392
395
  options: { nullable: true; optional?: true },
393
- ): TableDef<ElementOf<E>[] | null, true, true>
396
+ ): TableDef<PgArray<ElementOf<E>> | null, true, true>
394
397
  },
395
398
 
396
399
  /** True/false: `BOOLEAN` on Postgres, `TINYINT(1)` on MySQL. */
package/src/index.ts CHANGED
@@ -21,6 +21,12 @@ export type {
21
21
  * module that can open a database connection.
22
22
  */
23
23
  export { getQueryObserver, setQueryObserver } from './adapters/observe'
24
+ /**
25
+ * The row type of a `Field.Array` column, exported because row types name it:
26
+ * a plain array to read, `DB.array()` to write. `Field.Sql<PgArray<string>>`
27
+ * declares an array the same way for a SQL type `Field.Array` does not spell.
28
+ */
29
+ export type { PgArray } from './array-value'
24
30
  export type {
25
31
  InferOptionals,
26
32
  InferSchema,
@@ -1,6 +1,7 @@
1
1
  import { Try } from '@bakery-framework/core/utils'
2
2
  import { throws } from '@bakery-framework/core/utils/common'
3
3
  import { DEFAULT_MAX_QUERY_PARAMS, type SQLAdapter } from '../adapters'
4
+ import type { InsertRecord } from '../array-value'
4
5
  import { getActiveDb, txStorage } from '../connection'
5
6
  import type {
6
7
  AppViews,
@@ -52,10 +53,7 @@ export namespace Mutation {
52
53
  }
53
54
 
54
55
  export type InsertSchema<T extends Tables> = T extends keyof DBSchema
55
- ? Prettify<
56
- Omit<DBSchema[T], ValidOptionals<T>> &
57
- Partial<Pick<DBSchema[T], ValidOptionals<T>>>
58
- >
56
+ ? Prettify<InsertRecord<DBSchema[T], ValidOptionals<T>>>
59
57
  : MapOf<unknown>
60
58
 
61
59
  export type UpdateSchema<T extends Tables> = Partial<InsertSchema<T>>
package/src/orm/query.ts CHANGED
@@ -136,6 +136,7 @@ export namespace DB {
136
136
  | schemaColumnRef<C>
137
137
  | QBRaw
138
138
  | QBObject
139
+ | ArrayValue
139
140
  | string
140
141
  | number
141
142
  | boolean