@primate/core 0.9.10 → 0.9.12

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.
@@ -132,6 +132,29 @@ export default (db) => {
132
132
  name: p.string.default("Donald"),
133
133
  },
134
134
  });
135
+ test.case("insert type accepts explicit undefined for write-optional fields", assert => {
136
+ const insert = {
137
+ age: undefined,
138
+ id: undefined,
139
+ name: undefined,
140
+ lastname: undefined,
141
+ };
142
+ assert(insert).type();
143
+ User.insert({
144
+ age: undefined,
145
+ id: undefined,
146
+ name: undefined,
147
+ lastname: undefined,
148
+ });
149
+ });
150
+ test.case("insert type survives omit", assert => {
151
+ const insert = {
152
+ age: undefined,
153
+ id: undefined,
154
+ lastname: undefined,
155
+ };
156
+ assert(insert).type();
157
+ });
135
158
  const UserN = store({
136
159
  table: "user_n",
137
160
  db,
@@ -317,7 +340,9 @@ export default (db) => {
317
340
  });
318
341
  }
319
342
  function bad_where(label, mk, expected) {
320
- return security_pair("where", label, mk, base => User.find({ where: base }), w => Author.find({ with: { articles: { store: Article, where: w } } }), expected);
343
+ return security_pair("where", label, mk, base => User.find({ where: base }), w => Author.find({
344
+ with: { articles: { store: Article, where: w } },
345
+ }), expected);
321
346
  }
322
347
  function bad_select(label, mk, expected) {
323
348
  return security_pair("find", label, mk, base => User.find({ select: base }), w => Author.find({ with: { articles: { store: Article, select: w } } }), expected);
@@ -1084,7 +1109,9 @@ export default (db) => {
1084
1109
  //const missing = `missing-${Date.now()}-${Math.random()}`;
1085
1110
  const missing = "00000000-0000-4000-8000-000000000000";
1086
1111
  await throws(assert, Code.record_not_found, () => Article.get(missing, { with: { author: Author } }));
1087
- assert(await Article.try(missing, { with: { author: Author } })).undefined();
1112
+ assert(await Article.try(missing, {
1113
+ with: { author: Author },
1114
+ })).undefined();
1088
1115
  });
1089
1116
  $rel("get/try: missing id (+ parent)", async (assert) => {
1090
1117
  const missing = "00000000-0000-4000-8000-000000000000";
@@ -1287,7 +1314,8 @@ export default (db) => {
1287
1314
  assert(rows.length).equals(1);
1288
1315
  assert(rows[0].id).equals(u.id);
1289
1316
  });
1290
- /*$store("json column: inferred type on insert", AuthorWithJSON, async assert => {
1317
+ /*$store("json column: inferred type on insert", AuthorWithJSON,
1318
+ async assert => {
1291
1319
  const author = await AuthorWithJSON.insert({
1292
1320
  name: "John",
1293
1321
  articles: [{ title: "First", published: new Date() }],
@@ -1322,7 +1350,9 @@ export default (db) => {
1322
1350
  });
1323
1351
  const author = await AuthorWithJSON.get(a.id);
1324
1352
 
1325
- assert(author.articles).type<{ title: string; published: Date }[] | undefined>();
1353
+ assert(author.articles).type<{
1354
+ title: string; published: Date
1355
+ }[] | undefined>();
1326
1356
  assert(author.meta).type<{ views: number; tags: string[] } | undefined>();
1327
1357
  assert(author.notes).type<JSONValue | undefined>();
1328
1358
 
@@ -1331,7 +1361,8 @@ export default (db) => {
1331
1361
  assert(author.articles?.[0].published).type<Date | undefined>();
1332
1362
  });
1333
1363
 
1334
- $store("json column: roundtrip preserves types", AuthorWithJSON, async assert => {
1364
+ $store("json column: roundtrip preserves types", AuthorWithJSON,
1365
+ async assert => {
1335
1366
  const now = new Date();
1336
1367
  const a = await AuthorWithJSON.insert({
1337
1368
  name: "John",
@@ -1354,7 +1385,9 @@ export default (db) => {
1354
1385
  await AuthorWithJSON.find({ where: { meta: { tags: { $like: "%ts%" } } } });
1355
1386
 
1356
1387
  // $contains always available, untyped
1357
- await AuthorWithJSON.find({ where: { articles: { $contains: { title: "First" } } } });
1388
+ await AuthorWithJSON.find({ where: {
1389
+ articles: { $contains: { title: "First" } } },
1390
+ });
1358
1391
  });*/
1359
1392
  $user("where: null matches unset via update", async (assert) => {
1360
1393
  const [paul] = await User.find({ where: { name: "Paul" } });
@@ -1571,7 +1604,7 @@ export default (db) => {
1571
1604
  select: ["name"],
1572
1605
  with: {
1573
1606
  articles: {
1574
- store: Article, select: ["title"], sort: { title: "asc" }
1607
+ store: Article, select: ["title"], sort: { title: "asc" },
1575
1608
  },
1576
1609
  },
1577
1610
  sort: { name: "asc" },
@@ -1622,7 +1655,9 @@ export default (db) => {
1622
1655
  id: key.primary(p.uuid),
1623
1656
  parent_id: key.foreign(p.uuid),
1624
1657
  url: p.url.optional(),
1625
- parent: relation.one({ table: "j_parent", by: "parent_id", reverse: true }),
1658
+ parent: relation.one({
1659
+ table: "j_parent", by: "parent_id", reverse: true,
1660
+ }),
1626
1661
  },
1627
1662
  });
1628
1663
  await Parent.create();
@@ -1636,7 +1671,7 @@ export default (db) => {
1636
1671
  parent_id: p0.id,
1637
1672
  url: new URL("https://example.com/joined"),
1638
1673
  });
1639
- // IMPORTANT: force joined path + projection that omits pk, but still must join.
1674
+ // force joined path + projection that omits pk, but still must join
1640
1675
  const [got] = await Parent.find({
1641
1676
  where: { id: p0.id },
1642
1677
  select: ["url"],
@@ -1645,11 +1680,12 @@ export default (db) => {
1645
1680
  assert(got).defined();
1646
1681
  // pk must not leak
1647
1682
  assert("id" in got).false();
1648
- // ---- base assertion (should fail if joined base isn't unbound/decoded)
1683
+ // base assertion (should fail if joined base isn't unbound/decoded)
1649
1684
  assert(got.url).type();
1650
1685
  assert(got.url instanceof URL).true();
1651
1686
  assert(got.url.href).equals("https://example.com/parent");
1652
- // ---- relation assertion (should fail if joined relation isn't unbound/decoded)
1687
+ // relation assertion (should fail if joined relation isn't
1688
+ // unbound/decoded)
1653
1689
  assert(Array.isArray(got.children)).true();
1654
1690
  assert(got.children.length).equals(1);
1655
1691
  const c0 = got.children[0];
@@ -1912,7 +1948,7 @@ export default (db) => {
1912
1948
  $user("find: offset skips records", async (assert) => {
1913
1949
  const all = await User.find({ sort: { name: "asc" } });
1914
1950
  const offset = await User.find({
1915
- sort: { name: "asc" }, offset: 2, limit: all.length - 2
1951
+ sort: { name: "asc" }, offset: 2, limit: all.length - 2,
1916
1952
  });
1917
1953
  assert(offset.length).equals(all.length - 2);
1918
1954
  assert(offset[0].name).equals(all[2].name);
@@ -1920,7 +1956,7 @@ export default (db) => {
1920
1956
  $user("find: offset 0 is same as no offset", async (assert) => {
1921
1957
  const without = await User.find({ sort: { name: "asc" } });
1922
1958
  const with_zero = await User.find({
1923
- sort: { name: "asc" }, offset: 0, limit: without.length
1959
+ sort: { name: "asc" }, offset: 0, limit: without.length,
1924
1960
  });
1925
1961
  assert(with_zero.length).equals(without.length);
1926
1962
  assert(with_zero.map(r => r.name)).equals(without.map(r => r.name));
@@ -8,7 +8,7 @@ import type Init from "#store/Init";
8
8
  import type PrimaryKey from "#store/PrimaryKey";
9
9
  import type { ManyRelation, OneRelation, Relation } from "#store/relation";
10
10
  import type StoreInput from "#store/StoreInput";
11
- import type { Dict, Serializable } from "@rcompat/type";
11
+ import type { Dict, Serializable, Unpack } from "@rcompat/type";
12
12
  import type { DefaultType, InferStore, Storable } from "pema";
13
13
  import StoreType from "pema/StoreType";
14
14
  declare const brand: unique symbol;
@@ -18,9 +18,6 @@ type X<T> = {
18
18
  type OrNull<T> = {
19
19
  [P in keyof T]?: null | T[P] | undefined;
20
20
  };
21
- type Optional<T> = {
22
- [P in keyof T]?: T[P] | undefined;
23
- };
24
21
  type StringOperators = {
25
22
  $like?: string;
26
23
  $ilike?: string;
@@ -62,7 +59,7 @@ type Projected<T, S extends Select<T> | undefined> = S extends readonly (keyof T
62
59
  type DefaultFields<T extends StoreInput> = {
63
60
  [K in keyof InferRecord<T>]: T[K] extends DefaultType<any, any> ? K : never;
64
61
  }[keyof InferRecord<T>];
65
- type Insertable<T extends StoreInput> = X<Omit<InferRecord<T>, PrimaryKeyField<T> | DefaultFields<T>> & Optional<Pick<InferRecord<T>, PrimaryKeyField<T> | DefaultFields<T>>>>;
62
+ type Insertable<T extends StoreInput> = Omit<InferRecord<T>, PrimaryKeyField<T> | DefaultFields<T>> & Partial<Pick<InferRecord<T>, PrimaryKeyField<T> | DefaultFields<T>>>;
66
63
  type PrimaryKeyField<T extends StoreInput> = {
67
64
  [K in keyof T]: T[K] extends PrimaryKey<any> ? K : never;
68
65
  }[keyof T] & keyof InferRecord<T>;
@@ -100,7 +97,7 @@ type ReadSort = Dict<"asc" | "desc">;
100
97
  export default class Store<T extends StoreInput, N extends string = string> implements Serializable {
101
98
  #private;
102
99
  [brand]: boolean;
103
- readonly Insert: Insertable<T>;
100
+ readonly Insert: Unpack<Insertable<T>>;
104
101
  readonly Schema: Schema<T>;
105
102
  static is(x: unknown): x is Store<any, any>;
106
103
  constructor(init: Init<T, N>);
@@ -3,7 +3,9 @@ import key from "#store/key";
3
3
  import relation from "#store/relation";
4
4
  import Store from "#store/Store";
5
5
  import type StoreInput from "#store/StoreInput";
6
- declare function store<T extends StoreInput, const N extends string = string>(init: Init<T, N>): Store<T, N>;
6
+ declare function store<T extends StoreInput, const N extends string = string>(init: Omit<Init<T, N>, "schema"> & {
7
+ schema: T;
8
+ }): Store<T, N>;
7
9
  declare namespace store {
8
10
  export { key };
9
11
  export { relation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/core",
3
- "version": "0.9.10",
3
+ "version": "0.9.12",
4
4
  "description": "The universal web framework",
5
5
  "homepage": "https://primate.run",
6
6
  "bugs": "https://github.com/primate-run/primate/issues",