@rebasepro/server-postgresql 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e

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 (136) hide show
  1. package/dist/common/src/collections/CollectionRegistry.d.ts +8 -0
  2. package/dist/common/src/util/entities.d.ts +22 -0
  3. package/dist/common/src/util/relations.d.ts +14 -4
  4. package/dist/common/src/util/resolutions.d.ts +1 -1
  5. package/dist/index.es.js +1254 -591
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +1254 -591
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +17 -29
  10. package/dist/server-postgresql/src/auth/services.d.ts +7 -3
  11. package/dist/server-postgresql/src/collections/PostgresCollectionRegistry.d.ts +1 -1
  12. package/dist/server-postgresql/src/connection.d.ts +34 -1
  13. package/dist/server-postgresql/src/data-transformer.d.ts +26 -4
  14. package/dist/server-postgresql/src/databasePoolManager.d.ts +2 -2
  15. package/dist/server-postgresql/src/schema/auth-schema.d.ts +139 -38
  16. package/dist/server-postgresql/src/schema/doctor-cli.d.ts +2 -0
  17. package/dist/server-postgresql/src/schema/doctor.d.ts +43 -0
  18. package/dist/server-postgresql/src/schema/generate-drizzle-schema-logic.d.ts +1 -1
  19. package/dist/server-postgresql/src/schema/test-schema.d.ts +24 -0
  20. package/dist/server-postgresql/src/services/EntityFetchService.d.ts +22 -8
  21. package/dist/server-postgresql/src/services/EntityPersistService.d.ts +1 -1
  22. package/dist/server-postgresql/src/services/RelationService.d.ts +11 -5
  23. package/dist/server-postgresql/src/services/entity-helpers.d.ts +16 -2
  24. package/dist/server-postgresql/src/services/entityService.d.ts +8 -6
  25. package/dist/server-postgresql/src/services/realtimeService.d.ts +2 -0
  26. package/dist/server-postgresql/src/utils/drizzle-conditions.d.ts +2 -2
  27. package/dist/types/src/controllers/auth.d.ts +2 -0
  28. package/dist/types/src/controllers/client.d.ts +119 -7
  29. package/dist/types/src/controllers/collection_registry.d.ts +4 -3
  30. package/dist/types/src/controllers/customization_controller.d.ts +7 -1
  31. package/dist/types/src/controllers/data.d.ts +34 -7
  32. package/dist/types/src/controllers/data_driver.d.ts +20 -28
  33. package/dist/types/src/controllers/database_admin.d.ts +2 -2
  34. package/dist/types/src/controllers/email.d.ts +34 -0
  35. package/dist/types/src/controllers/index.d.ts +1 -0
  36. package/dist/types/src/controllers/local_config_persistence.d.ts +4 -4
  37. package/dist/types/src/controllers/navigation.d.ts +5 -5
  38. package/dist/types/src/controllers/registry.d.ts +6 -3
  39. package/dist/types/src/controllers/side_entity_controller.d.ts +7 -6
  40. package/dist/types/src/controllers/storage.d.ts +24 -26
  41. package/dist/types/src/rebase_context.d.ts +8 -4
  42. package/dist/types/src/types/backend.d.ts +4 -1
  43. package/dist/types/src/types/builders.d.ts +5 -4
  44. package/dist/types/src/types/chips.d.ts +1 -1
  45. package/dist/types/src/types/collections.d.ts +169 -125
  46. package/dist/types/src/types/cron.d.ts +102 -0
  47. package/dist/types/src/types/data_source.d.ts +1 -1
  48. package/dist/types/src/types/entity_actions.d.ts +8 -8
  49. package/dist/types/src/types/entity_callbacks.d.ts +15 -15
  50. package/dist/types/src/types/entity_link_builder.d.ts +1 -1
  51. package/dist/types/src/types/entity_overrides.d.ts +2 -1
  52. package/dist/types/src/types/entity_views.d.ts +8 -8
  53. package/dist/types/src/types/export_import.d.ts +3 -3
  54. package/dist/types/src/types/index.d.ts +1 -0
  55. package/dist/types/src/types/plugins.d.ts +72 -18
  56. package/dist/types/src/types/properties.d.ts +118 -33
  57. package/dist/types/src/types/relations.d.ts +1 -1
  58. package/dist/types/src/types/slots.d.ts +30 -6
  59. package/dist/types/src/types/translations.d.ts +44 -0
  60. package/dist/types/src/types/user_management_delegate.d.ts +1 -0
  61. package/drizzle-test/0000_woozy_junta.sql +6 -0
  62. package/drizzle-test/0001_youthful_arachne.sql +1 -0
  63. package/drizzle-test/0002_lively_dragon_lord.sql +2 -0
  64. package/drizzle-test/0003_mean_king_cobra.sql +2 -0
  65. package/drizzle-test/meta/0000_snapshot.json +47 -0
  66. package/drizzle-test/meta/0001_snapshot.json +48 -0
  67. package/drizzle-test/meta/0002_snapshot.json +38 -0
  68. package/drizzle-test/meta/0003_snapshot.json +48 -0
  69. package/drizzle-test/meta/_journal.json +34 -0
  70. package/drizzle-test-out/0000_tan_trauma.sql +6 -0
  71. package/drizzle-test-out/0001_rapid_drax.sql +1 -0
  72. package/drizzle-test-out/meta/0000_snapshot.json +44 -0
  73. package/drizzle-test-out/meta/0001_snapshot.json +54 -0
  74. package/drizzle-test-out/meta/_journal.json +20 -0
  75. package/drizzle.test.config.ts +10 -0
  76. package/package.json +88 -89
  77. package/scratch.ts +41 -0
  78. package/src/PostgresBackendDriver.ts +63 -79
  79. package/src/PostgresBootstrapper.ts +7 -8
  80. package/src/auth/ensure-tables.ts +158 -86
  81. package/src/auth/services.ts +109 -50
  82. package/src/cli.ts +259 -16
  83. package/src/collections/PostgresCollectionRegistry.ts +6 -6
  84. package/src/connection.ts +70 -48
  85. package/src/data-transformer.ts +155 -116
  86. package/src/databasePoolManager.ts +6 -5
  87. package/src/history/HistoryService.ts +3 -12
  88. package/src/interfaces.ts +3 -3
  89. package/src/schema/auth-schema.ts +26 -3
  90. package/src/schema/doctor-cli.ts +47 -0
  91. package/src/schema/doctor.ts +595 -0
  92. package/src/schema/generate-drizzle-schema-logic.ts +204 -57
  93. package/src/schema/generate-drizzle-schema.ts +6 -6
  94. package/src/schema/test-schema.ts +11 -0
  95. package/src/services/BranchService.ts +5 -5
  96. package/src/services/EntityFetchService.ts +317 -188
  97. package/src/services/EntityPersistService.ts +15 -17
  98. package/src/services/RelationService.ts +299 -37
  99. package/src/services/entity-helpers.ts +39 -13
  100. package/src/services/entityService.ts +11 -9
  101. package/src/services/realtimeService.ts +58 -29
  102. package/src/utils/drizzle-conditions.ts +25 -24
  103. package/src/websocket.ts +52 -21
  104. package/test/auth-services.test.ts +131 -39
  105. package/test/batch-many-to-many-regression.test.ts +573 -0
  106. package/test/branchService.test.ts +22 -12
  107. package/test/data-transformer-hardening.test.ts +417 -0
  108. package/test/data-transformer.test.ts +175 -0
  109. package/test/doctor.test.ts +182 -0
  110. package/test/entityService.errors.test.ts +31 -16
  111. package/test/entityService.relations.test.ts +155 -59
  112. package/test/entityService.subcollection-search.test.ts +107 -57
  113. package/test/entityService.test.ts +105 -47
  114. package/test/generate-drizzle-schema.test.ts +262 -69
  115. package/test/historyService.test.ts +31 -16
  116. package/test/n-plus-one-regression.test.ts +314 -0
  117. package/test/postgresDataDriver.test.ts +260 -168
  118. package/test/realtimeService.test.ts +70 -39
  119. package/test/relation-pipeline-gaps.test.ts +637 -0
  120. package/test/relations.test.ts +492 -39
  121. package/test-drizzle-bug.ts +18 -0
  122. package/test-drizzle-out/0000_cultured_freak.sql +7 -0
  123. package/test-drizzle-out/0001_tiresome_professor_monster.sql +1 -0
  124. package/test-drizzle-out/meta/0000_snapshot.json +55 -0
  125. package/test-drizzle-out/meta/0001_snapshot.json +63 -0
  126. package/test-drizzle-out/meta/_journal.json +20 -0
  127. package/test-drizzle-prompt.sh +2 -0
  128. package/test-policy-prompt.sh +3 -0
  129. package/test-programmatic.ts +30 -0
  130. package/test-programmatic2.ts +59 -0
  131. package/test-schema-no-policies.ts +12 -0
  132. package/test_drizzle_mock.js +2 -2
  133. package/test_find_changed.mjs +3 -1
  134. package/test_hash.js +14 -0
  135. package/tsconfig.json +1 -1
  136. package/vite.config.ts +5 -5
@@ -0,0 +1,182 @@
1
+ import { EntityCollection, StringProperty, NumberProperty, DateProperty, ArrayProperty, Property } from "@rebasepro/types";
2
+ import { generateSchema } from "../src/schema/generate-drizzle-schema-logic";
3
+ import { checkCollectionsVsSchema, getExpectedColumnType } from "../src/schema/doctor";
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import { tmpdir } from "os";
7
+
8
+ // Re-export for testing — we need to access the internal helper
9
+ // but since it's not exported, we test it indirectly via checkCollectionsVsSchema
10
+
11
+ describe("Rebase Schema Doctor", () => {
12
+
13
+ describe("checkCollectionsVsSchema", () => {
14
+ const createTempSchemaFile = async (content: string): Promise<string> => {
15
+ const dir = fs.mkdtempSync(path.join(tmpdir(), "doctor-test-"));
16
+ const filePath = path.join(dir, "schema.generated.ts");
17
+ fs.writeFileSync(filePath, content, "utf-8");
18
+ return filePath;
19
+ };
20
+
21
+ it("should detect missing schema file", async () => {
22
+ const collections: EntityCollection[] = [{
23
+ slug: "products",
24
+ table: "products",
25
+ name: "Products",
26
+ properties: { name: { type: "string" } }
27
+ }];
28
+
29
+ const result = await checkCollectionsVsSchema(collections, "/nonexistent/path/schema.generated.ts");
30
+ expect(result.passed).toBe(false);
31
+ expect(result.issues).toHaveLength(1);
32
+ expect(result.issues[0].category).toBe("schema_stale");
33
+ expect(result.issues[0].severity).toBe("error");
34
+ });
35
+
36
+ it("should pass when schema matches collections", async () => {
37
+ const collections: EntityCollection[] = [{
38
+ slug: "products",
39
+ table: "products",
40
+ name: "Products",
41
+ properties: {
42
+ name: { type: "string" },
43
+ price: { type: "number" }
44
+ }
45
+ }];
46
+
47
+ // Generate the expected schema and write to temp file
48
+ const expectedSchema = await generateSchema(collections);
49
+ const schemaPath = await createTempSchemaFile(expectedSchema);
50
+
51
+ try {
52
+ const result = await checkCollectionsVsSchema(collections, schemaPath);
53
+ expect(result.passed).toBe(true);
54
+ expect(result.issues).toHaveLength(0);
55
+ } finally {
56
+ fs.rmSync(path.dirname(schemaPath), { recursive: true });
57
+ }
58
+ });
59
+
60
+ it("should detect stale schema when collections have changed", async () => {
61
+ const originalCollections: EntityCollection[] = [{
62
+ slug: "products",
63
+ table: "products",
64
+ name: "Products",
65
+ properties: { name: { type: "string" } }
66
+ }];
67
+
68
+ const updatedCollections: EntityCollection[] = [{
69
+ slug: "products",
70
+ table: "products",
71
+ name: "Products",
72
+ properties: {
73
+ name: { type: "string" },
74
+ price: { type: "number" } // New field added
75
+ }
76
+ }];
77
+
78
+ // Write schema for original, check against updated
79
+ const originalSchema = await generateSchema(originalCollections);
80
+ const schemaPath = await createTempSchemaFile(originalSchema);
81
+
82
+ try {
83
+ const result = await checkCollectionsVsSchema(updatedCollections, schemaPath);
84
+ expect(result.passed).toBe(false);
85
+ expect(result.issues.some(i => i.category === "schema_stale")).toBe(true);
86
+ } finally {
87
+ fs.rmSync(path.dirname(schemaPath), { recursive: true });
88
+ }
89
+ });
90
+
91
+ it("should return error for nonexistent schema file even with empty collections", async () => {
92
+ const result = await checkCollectionsVsSchema([], "/nonexistent/path");
93
+ // Schema file doesn't exist → error regardless of collection count
94
+ expect(result.passed).toBe(false);
95
+ expect(result.issues[0].category).toBe("schema_stale");
96
+ });
97
+ });
98
+
99
+ describe("column type mapping", () => {
100
+ // We test getExpectedColumnType indirectly through import
101
+ // These are integration-style tests against the mapping logic
102
+
103
+ it("should map string types correctly", () => {
104
+ expect(getExpectedColumnType({ type: "string" })).toBe("character varying");
105
+ expect(getExpectedColumnType({ type: "string",
106
+ columnType: "text" } as StringProperty)).toBe("text");
107
+ expect(getExpectedColumnType({ type: "string",
108
+ columnType: "char" } as StringProperty)).toBe("character");
109
+ });
110
+
111
+ it("should map number types correctly", () => {
112
+ expect(getExpectedColumnType({ type: "number" })).toBe("numeric");
113
+ expect(getExpectedColumnType({ type: "number",
114
+ validation: { integer: true } } as NumberProperty)).toBe("integer");
115
+ expect(getExpectedColumnType({ type: "number",
116
+ columnType: "real" } as NumberProperty)).toBe("real");
117
+ expect(getExpectedColumnType({ type: "number",
118
+ columnType: "double precision" } as NumberProperty)).toBe("double precision");
119
+ expect(getExpectedColumnType({ type: "number",
120
+ columnType: "bigint" } as NumberProperty)).toBe("bigint");
121
+ });
122
+
123
+ it("should map boolean type correctly", () => {
124
+ expect(getExpectedColumnType({ type: "boolean" })).toBe("boolean");
125
+ });
126
+
127
+ it("should map date types correctly", () => {
128
+ expect(getExpectedColumnType({ type: "date" })).toBe("timestamp with time zone");
129
+ expect(getExpectedColumnType({ type: "date",
130
+ columnType: "date" } as DateProperty)).toBe("date");
131
+ expect(getExpectedColumnType({ type: "date",
132
+ columnType: "time" } as DateProperty)).toBe("time without time zone");
133
+ });
134
+
135
+ it("should map json types correctly", () => {
136
+ expect(getExpectedColumnType({ type: "map" })).toBe("jsonb");
137
+ expect(getExpectedColumnType({ type: "array" })).toBe("jsonb");
138
+ expect(getExpectedColumnType({ type: "array",
139
+ columnType: "json" } as ArrayProperty)).toBe("json");
140
+ });
141
+
142
+ it("should map enum string to USER-DEFINED", () => {
143
+ expect(getExpectedColumnType({
144
+ type: "string",
145
+ enum: { active: "Active",
146
+ inactive: "Inactive" }
147
+ } as StringProperty)).toBe("USER-DEFINED");
148
+ });
149
+
150
+ it("should return null for relation type", () => {
151
+ expect(getExpectedColumnType({ type: "relation" } as Property)).toBe(null);
152
+ });
153
+ });
154
+
155
+ describe("report generation", () => {
156
+ it("should correctly count errors and warnings in summary", () => {
157
+ const issues = [
158
+ { severity: "error" as const,
159
+ category: "missing_table" as const,
160
+ table: "t1",
161
+ message: "m",
162
+ fix: "f" },
163
+ { severity: "warning" as const,
164
+ category: "type_mismatch" as const,
165
+ table: "t2",
166
+ message: "m",
167
+ fix: "f" },
168
+ { severity: "error" as const,
169
+ category: "missing_column" as const,
170
+ table: "t3",
171
+ message: "m",
172
+ fix: "f" }
173
+ ];
174
+
175
+ const errors = issues.filter(i => i.severity === "error").length;
176
+ const warnings = issues.filter(i => i.severity === "warning").length;
177
+
178
+ expect(errors).toBe(2);
179
+ expect(warnings).toBe(1);
180
+ });
181
+ });
182
+ });
@@ -9,7 +9,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
9
9
  let db: jest.Mocked<NodePgDatabase<any>>;
10
10
 
11
11
  const mockTable = {
12
- id: { name: "id", dataType: "number" },
12
+ id: { name: "id",
13
+ dataType: "number" },
13
14
  name: { name: "name" },
14
15
  _def: { tableName: "test_table" }
15
16
  };
@@ -52,7 +53,7 @@ describe("EntityService - Error Handling & Edge Cases", () => {
52
53
  update: jest.fn().mockReturnThis(),
53
54
  set: jest.fn().mockReturnThis(),
54
55
  delete: jest.fn().mockReturnThis(),
55
- transaction: jest.fn((callback) => callback(db)),
56
+ transaction: jest.fn((callback) => callback(db))
56
57
  } as any;
57
58
 
58
59
  // Add a then method to make the db object awaitable when the query chain ends
@@ -81,7 +82,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
81
82
 
82
83
  describe("ID Type Validation", () => {
83
84
  it("should handle valid numeric ID strings", async () => {
84
- const mockEntity = { id: 123, name: "Test" };
85
+ const mockEntity = { id: 123,
86
+ name: "Test" };
85
87
  db.limit.mockResolvedValue([mockEntity]);
86
88
 
87
89
  const entity = await entityService.fetchEntity("test", "123");
@@ -95,7 +97,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
95
97
  });
96
98
 
97
99
  it("should handle zero as valid ID", async () => {
98
- const mockEntity = { id: 0, name: "Test" };
100
+ const mockEntity = { id: 0,
101
+ name: "Test" };
99
102
  db.limit.mockResolvedValue([mockEntity]);
100
103
 
101
104
  const entity = await entityService.fetchEntity("test", 0);
@@ -103,7 +106,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
103
106
  });
104
107
 
105
108
  it("should handle negative numbers as valid ID", async () => {
106
- const mockEntity = { id: -1, name: "Test" };
109
+ const mockEntity = { id: -1,
110
+ name: "Test" };
107
111
  db.limit.mockResolvedValue([mockEntity]);
108
112
 
109
113
  const entity = await entityService.fetchEntity("test", -1);
@@ -176,7 +180,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
176
180
 
177
181
  describe("Concurrent Operations", () => {
178
182
  it("should handle multiple simultaneous reads", async () => {
179
- const mockEntity = { id: 1, name: "Test" };
183
+ const mockEntity = { id: 1,
184
+ name: "Test" };
180
185
  db.limit.mockResolvedValue([mockEntity]);
181
186
 
182
187
  const promises = Array(10).fill(0).map(() =>
@@ -193,7 +198,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
193
198
 
194
199
  it("should handle race conditions in write operations", async () => {
195
200
  db.returning.mockResolvedValue([{ id: 1 }]);
196
- db.limit.mockResolvedValue([{ id: 1, name: "Updated" }]);
201
+ db.limit.mockResolvedValue([{ id: 1,
202
+ name: "Updated" }]);
197
203
 
198
204
  const promises = Array(5).fill(0).map((_, i) =>
199
205
  entityService.saveEntity("test", { name: `Update ${i}` }, 1)
@@ -243,7 +249,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
243
249
  const incompleteEntity = {}; // Missing required fields
244
250
 
245
251
  db.returning.mockResolvedValue([{ id: 1 }]);
246
- db.limit.mockResolvedValue([{ id: 1, name: null }]);
252
+ db.limit.mockResolvedValue([{ id: 1,
253
+ name: null }]);
247
254
 
248
255
  // The service should handle validation at the collection level
249
256
  // This test verifies the service doesn't crash with incomplete data
@@ -252,7 +259,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
252
259
  });
253
260
 
254
261
  it("should handle NULL values in database correctly", async () => {
255
- const mockEntity = { id: 1, name: null };
262
+ const mockEntity = { id: 1,
263
+ name: null };
256
264
  db.limit.mockResolvedValue([mockEntity]);
257
265
 
258
266
  const entity = await entityService.fetchEntity("test", 1);
@@ -263,7 +271,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
263
271
  const entityWithUndefined = { name: undefined };
264
272
 
265
273
  db.returning.mockResolvedValue([{ id: 1 }]);
266
- db.limit.mockResolvedValue([{ id: 1, name: null }]);
274
+ db.limit.mockResolvedValue([{ id: 1,
275
+ name: null }]);
267
276
 
268
277
  const entity = await entityService.saveEntity("test", entityWithUndefined);
269
278
  expect(entity.id).toBe("1");
@@ -276,7 +285,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
276
285
 
277
286
  // The service should handle this safely through parameterized queries
278
287
  // This test should not throw an error because of proper parameterization
279
- const mockEntity = { id: 1, name: "Safe" };
288
+ const mockEntity = { id: 1,
289
+ name: "Safe" };
280
290
  db.limit.mockResolvedValue([mockEntity]);
281
291
 
282
292
  const entity = await entityService.fetchEntity("test", maliciousId);
@@ -288,7 +298,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
288
298
  const entityWithLongValue = { name: veryLongString };
289
299
 
290
300
  db.returning.mockResolvedValue([{ id: 1 }]);
291
- db.limit.mockResolvedValue([{ id: 1, name: veryLongString }]);
301
+ db.limit.mockResolvedValue([{ id: 1,
302
+ name: veryLongString }]);
292
303
 
293
304
  const entity = await entityService.saveEntity("test", entityWithLongValue);
294
305
  expect(entity.values.name).toBe(veryLongString);
@@ -299,7 +310,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
299
310
  const entityWithSpecialChars = { name: specialChars };
300
311
 
301
312
  db.returning.mockResolvedValue([{ id: 1 }]);
302
- db.limit.mockResolvedValue([{ id: 1, name: specialChars }]);
313
+ db.limit.mockResolvedValue([{ id: 1,
314
+ name: specialChars }]);
303
315
 
304
316
  const entity = await entityService.saveEntity("test", entityWithSpecialChars);
305
317
  expect(entity.values.name).toBe(specialChars);
@@ -317,7 +329,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
317
329
  };
318
330
  jest.spyOn(collectionRegistry, "getCollectionByPath").mockReturnValue(booleanCollection);
319
331
 
320
- const mockEntity = { id: 1, active: false };
332
+ const mockEntity = { id: 1,
333
+ active: false };
321
334
  db.limit.mockResolvedValue([mockEntity]);
322
335
 
323
336
  const entity = await entityService.fetchEntity("test", 1);
@@ -334,7 +347,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
334
347
  };
335
348
  jest.spyOn(collectionRegistry, "getCollectionByPath").mockReturnValue(numericCollection);
336
349
 
337
- const mockEntity = { id: 1, count: 0 };
350
+ const mockEntity = { id: 1,
351
+ count: 0 };
338
352
  db.limit.mockResolvedValue([mockEntity]);
339
353
 
340
354
  const entity = await entityService.fetchEntity("test", 1);
@@ -342,7 +356,8 @@ describe("EntityService - Error Handling & Edge Cases", () => {
342
356
  });
343
357
 
344
358
  it("should handle empty string values correctly", async () => {
345
- const mockEntity = { id: 1, name: "" };
359
+ const mockEntity = { id: 1,
360
+ name: "" };
346
361
  db.limit.mockResolvedValue([mockEntity]);
347
362
 
348
363
  const entity = await entityService.fetchEntity("test", 1);