@proteinjs/db 1.32.3 → 1.34.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 (79) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/generated/index.js +1 -1
  3. package/dist/generated/index.js.map +1 -1
  4. package/dist/generated/test/index.d.ts.map +1 -1
  5. package/dist/generated/test/index.js +15 -1
  6. package/dist/generated/test/index.js.map +1 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +6 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/src/Db.d.ts +2 -0
  12. package/dist/src/Db.d.ts.map +1 -1
  13. package/dist/src/Db.js +33 -62
  14. package/dist/src/Db.js.map +1 -1
  15. package/dist/src/MigrationRunner.d.ts +14 -3
  16. package/dist/src/MigrationRunner.d.ts.map +1 -1
  17. package/dist/src/MigrationRunner.js +56 -28
  18. package/dist/src/MigrationRunner.js.map +1 -1
  19. package/dist/src/ReverseCascadeEdgeIndex.d.ts +51 -0
  20. package/dist/src/ReverseCascadeEdgeIndex.d.ts.map +1 -0
  21. package/dist/src/ReverseCascadeEdgeIndex.js +108 -0
  22. package/dist/src/ReverseCascadeEdgeIndex.js.map +1 -0
  23. package/dist/src/Table.d.ts +34 -7
  24. package/dist/src/Table.d.ts.map +1 -1
  25. package/dist/src/Table.js +2 -7
  26. package/dist/src/Table.js.map +1 -1
  27. package/dist/src/schema/TableManager.d.ts +26 -0
  28. package/dist/src/schema/TableManager.d.ts.map +1 -1
  29. package/dist/src/schema/TableManager.js +154 -13
  30. package/dist/src/schema/TableManager.js.map +1 -1
  31. package/dist/src/source/SourceRecordLoader.d.ts +18 -1
  32. package/dist/src/source/SourceRecordLoader.d.ts.map +1 -1
  33. package/dist/src/source/SourceRecordLoader.js +187 -68
  34. package/dist/src/source/SourceRecordLoader.js.map +1 -1
  35. package/dist/src/tables/MigrationTable.d.ts +10 -6
  36. package/dist/src/tables/MigrationTable.d.ts.map +1 -1
  37. package/dist/src/tables/MigrationTable.js +3 -1
  38. package/dist/src/tables/MigrationTable.js.map +1 -1
  39. package/dist/test/index.d.ts +2 -0
  40. package/dist/test/index.d.ts.map +1 -1
  41. package/dist/test/index.js +2 -0
  42. package/dist/test/index.js.map +1 -1
  43. package/dist/test/reusable/CascadeDeleteTests.d.ts.map +1 -1
  44. package/dist/test/reusable/CascadeDeleteTests.js +59 -0
  45. package/dist/test/reusable/CascadeDeleteTests.js.map +1 -1
  46. package/dist/test/reusable/SourceRecordSyncTests.d.ts +11 -0
  47. package/dist/test/reusable/SourceRecordSyncTests.d.ts.map +1 -0
  48. package/dist/test/reusable/SourceRecordSyncTests.js +483 -0
  49. package/dist/test/reusable/SourceRecordSyncTests.js.map +1 -0
  50. package/dist/test/util/DbTestEnvironment.d.ts.map +1 -1
  51. package/dist/test/util/DbTestEnvironment.js +2 -1
  52. package/dist/test/util/DbTestEnvironment.js.map +1 -1
  53. package/dist/test/util/tables/cascadeDeleteTestTables.d.ts +46 -0
  54. package/dist/test/util/tables/cascadeDeleteTestTables.d.ts.map +1 -1
  55. package/dist/test/util/tables/cascadeDeleteTestTables.js +51 -1
  56. package/dist/test/util/tables/cascadeDeleteTestTables.js.map +1 -1
  57. package/dist/test/util/tables/crudTestTables.d.ts +1 -1
  58. package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts +82 -0
  59. package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts.map +1 -0
  60. package/dist/test/util/tables/sourceRecordSyncTestTables.js +90 -0
  61. package/dist/test/util/tables/sourceRecordSyncTestTables.js.map +1 -0
  62. package/dist/test/util/tables/transactionTestTables.d.ts +1 -1
  63. package/generated/index.ts +1 -1
  64. package/generated/test/index.ts +15 -1
  65. package/index.ts +4 -0
  66. package/package.json +2 -2
  67. package/src/Db.ts +32 -57
  68. package/src/MigrationRunner.ts +29 -4
  69. package/src/ReverseCascadeEdgeIndex.ts +126 -0
  70. package/src/Table.ts +32 -9
  71. package/src/schema/TableManager.ts +98 -1
  72. package/src/source/SourceRecordLoader.ts +133 -23
  73. package/src/tables/MigrationTable.ts +12 -2
  74. package/test/index.ts +2 -0
  75. package/test/reusable/CascadeDeleteTests.ts +46 -0
  76. package/test/reusable/SourceRecordSyncTests.ts +288 -0
  77. package/test/util/DbTestEnvironment.ts +2 -0
  78. package/test/util/tables/cascadeDeleteTestTables.ts +48 -0
  79. package/test/util/tables/sourceRecordSyncTestTables.ts +84 -0
@@ -67,6 +67,19 @@ export interface Task extends Record {
67
67
  assigneeRef?: Reference<Worker> | null;
68
68
  }
69
69
 
70
+ // --- Reverse: DynamicReferenceColumn across multiple target tables (Mission -> Pilot | Robot)
71
+ export interface Pilot extends Record {
72
+ name: string;
73
+ }
74
+ export interface Robot extends Record {
75
+ name: string;
76
+ }
77
+ export interface Mission extends Record {
78
+ title: string;
79
+ assigneeTableName?: string | null;
80
+ assigneeRef?: Reference<Pilot | Robot> | null;
81
+ }
82
+
70
83
  /**
71
84
  * ---------- Table Names ----------
72
85
  */
@@ -94,6 +107,11 @@ const GROUP_ARR_REV_TABLE = 'db_test_cd_groups_arr_rev';
94
107
  const WORKER_TABLE = 'db_test_cd_workers';
95
108
  const TASK_TABLE = 'db_test_cd_tasks';
96
109
 
110
+ // Reverse (DynamicReferenceColumn, multiple targets)
111
+ const PILOT_TABLE = 'db_test_cd_pilots';
112
+ const ROBOT_TABLE = 'db_test_cd_robots';
113
+ const MISSION_TABLE = 'db_test_cd_missions';
114
+
97
115
  /**
98
116
  * ---------- Table Classes ----------
99
117
  */
@@ -216,6 +234,33 @@ export class TaskTable extends Table<Task> {
216
234
  });
217
235
  }
218
236
 
237
+ // Reverse: DynamicReferenceColumn across multiple target tables
238
+ export class PilotTable extends Table<Pilot> {
239
+ name = PILOT_TABLE;
240
+ columns = withRecordColumns<Pilot>({
241
+ name: new StringColumn('name'),
242
+ });
243
+ }
244
+ export class RobotTable extends Table<Robot> {
245
+ name = ROBOT_TABLE;
246
+ columns = withRecordColumns<Robot>({
247
+ name: new StringColumn('name'),
248
+ });
249
+ }
250
+ export class MissionTable extends Table<Mission> {
251
+ name = MISSION_TABLE;
252
+ columns = withRecordColumns<Mission>({
253
+ title: new StringColumn('title'),
254
+ assigneeTableName: new DynamicReferenceTableNameColumn('assignee_table_name', 'assignee_ref'),
255
+ assigneeRef: new DynamicReferenceColumn<Pilot | Robot>(
256
+ 'assignee_ref',
257
+ 'assignee_table_name',
258
+ false,
259
+ { reverseCascadeDelete: true } // reverse: deleting a Pilot OR a Robot deletes its Missions
260
+ ),
261
+ });
262
+ }
263
+
219
264
  export const cascadeDeleteTestTables = {
220
265
  MemberRef: new MemberRefTable() as Table<MemberRef>,
221
266
  GroupRef: new GroupRefTable() as Table<GroupRef>,
@@ -229,4 +274,7 @@ export const cascadeDeleteTestTables = {
229
274
  GroupArrRev: new GroupArrRevTable() as Table<GroupArrRev>,
230
275
  Worker: new WorkerTable() as Table<Worker>,
231
276
  Task: new TaskTable() as Table<Task>,
277
+ Pilot: new PilotTable() as Table<Pilot>,
278
+ Robot: new RobotTable() as Table<Robot>,
279
+ Mission: new MissionTable() as Table<Mission>,
232
280
  };
@@ -0,0 +1,84 @@
1
+ import {
2
+ Record as DbRecord,
3
+ SourceRecord,
4
+ StringColumn,
5
+ Table,
6
+ withRecordColumns,
7
+ withSourceRecordColumns,
8
+ } from '@proteinjs/db';
9
+
10
+ /**
11
+ * Fixtures for the source-record sync suites ({@link sourceRecordSyncTests}): a machine-account-
12
+ * shaped mixed table (natural-key adoption + flag-on-removed), a default-policy table (removed =
13
+ * deleted), a misdeclared natural-key table (non-unique column), and the two-generation table
14
+ * pair driving the unique-index duplicate preflight.
15
+ *
16
+ * The `sourceRecordOptions` literals are `as`-cast to the table's options type (not inferred):
17
+ * the cast also compiles against PRE-change `@proteinjs/db`, so the suites can run red-before-
18
+ * green against the old loader (which ignores these options) instead of failing at compile time.
19
+ */
20
+
21
+ export interface SyncMachineAccount extends SourceRecord {
22
+ email: string;
23
+ displayName?: string | null;
24
+ /** Declared by the loaders ('active') and patched by onSourceRemoved ('deactivated'). */
25
+ status?: string | null;
26
+ /** Runtime-owned: never declared, must survive every boot sync (the credential stand-in). */
27
+ runtimeNote?: string | null;
28
+ }
29
+
30
+ /** The machine-account shape: natural-key adoption by email, removed rows flagged not deleted. */
31
+ export class SyncMachineAccountTable extends Table<SyncMachineAccount> {
32
+ name = 'db_test_sync_machine_account';
33
+ columns = withSourceRecordColumns<SyncMachineAccount>({
34
+ email: new StringColumn('email', {
35
+ unique: { unique: true, indexName: 'db_test_sync_machine_account_email_unique' },
36
+ }),
37
+ displayName: new StringColumn('display_name'),
38
+ status: new StringColumn('status'),
39
+ runtimeNote: new StringColumn('runtime_note'),
40
+ });
41
+ sourceRecordOptions = {
42
+ naturalKey: 'email',
43
+ onSourceRemoved: { update: { status: 'deactivated' } },
44
+ } as Table<SyncMachineAccount>['sourceRecordOptions'];
45
+ }
46
+
47
+ export interface SyncDefaultPolicyRecord extends SourceRecord {
48
+ email: string;
49
+ displayName?: string | null;
50
+ }
51
+
52
+ /** Default options: id-keyed, removed source rows are deleted (today's behavior). */
53
+ export class SyncDefaultPolicyTable extends Table<SyncDefaultPolicyRecord> {
54
+ name = 'db_test_sync_default_policy';
55
+ columns = withSourceRecordColumns<SyncDefaultPolicyRecord>({
56
+ email: new StringColumn('email'),
57
+ displayName: new StringColumn('display_name'),
58
+ });
59
+ }
60
+
61
+ export interface DupePreflightRecord extends DbRecord {
62
+ email: string;
63
+ }
64
+
65
+ /** Generation 1: no uniqueness — the table under which duplicate rows accumulate. */
66
+ export class DupePreflightTable extends Table<DupePreflightRecord> {
67
+ name = 'db_test_dupe_preflight';
68
+ columns = withRecordColumns<DupePreflightRecord>({
69
+ email: new StringColumn('email'),
70
+ });
71
+ }
72
+
73
+ /** Generation 2: same table, email now unique — loading it runs the alter-path preflight. */
74
+ export class DupePreflightUniqueEmailTable extends Table<DupePreflightRecord> {
75
+ name = 'db_test_dupe_preflight';
76
+ columns = withRecordColumns<DupePreflightRecord>({
77
+ email: new StringColumn('email', { unique: { unique: true, indexName: 'db_test_dupe_preflight_email_unique' } }),
78
+ });
79
+ }
80
+
81
+ export const sourceRecordSyncTestTables = {
82
+ SyncMachineAccount: new SyncMachineAccountTable() as Table<SyncMachineAccount>,
83
+ SyncDefaultPolicy: new SyncDefaultPolicyTable() as Table<SyncDefaultPolicyRecord>,
84
+ };