@deterministic-code/datasources 0.1.0 → 0.1.1

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 (302) hide show
  1. package/dist/ArrayReader.d.ts +12 -0
  2. package/dist/BatchCommandIBulkWriteStrategy.d.ts +33 -0
  3. package/dist/BuiltRepository.d.ts +16 -0
  4. package/dist/BulkCRUDRepository.d.ts +17 -0
  5. package/dist/BulkCommand.d.ts +5 -0
  6. package/dist/BulkWriteEnrichment.d.ts +4 -0
  7. package/dist/CRUDRepository.d.ts +40 -0
  8. package/dist/CRUDRepositoryBuilder.d.ts +19 -0
  9. package/dist/CRUDRepositoryOptions.d.ts +7 -0
  10. package/dist/CRUDRepositoryStatements.d.ts +17 -0
  11. package/dist/CascadeDeleteEnrichmentStrategy.d.ts +7 -0
  12. package/dist/CascadeDeleteUpdateEnrichmentStrategy.d.ts +8 -0
  13. package/dist/CommandMiddlewareHost.d.ts +22 -0
  14. package/dist/ConsoleCommandMiddleware.d.ts +14 -0
  15. package/dist/CreateEnrichmentStrategy.d.ts +14 -0
  16. package/dist/Datasource.d.ts +30 -0
  17. package/dist/DatasourceError.d.ts +3 -0
  18. package/dist/DatasourceFactory.d.ts +12 -0
  19. package/dist/DatasourceOptions.d.ts +1 -0
  20. package/dist/DatasourceUrl.d.ts +12 -0
  21. package/dist/DatasourceUrlParser.d.ts +4 -0
  22. package/dist/DefaultCreateEnrichmentStrategy.d.ts +7 -0
  23. package/dist/DefaultReadonlyEnrichmentStrategy.d.ts +19 -0
  24. package/dist/DefaultUpdateEnrichmentStrategy.d.ts +7 -0
  25. package/dist/DefaultWriteEnrichmentStrategy.d.ts +21 -0
  26. package/dist/DeleteEnrichmentStrategy.d.ts +11 -0
  27. package/dist/DriverLoader.d.ts +5 -0
  28. package/dist/Enrichment.d.ts +13 -0
  29. package/dist/EnrichmentPropertyType.d.ts +7 -0
  30. package/dist/ExpectConsoleMiddleware.d.ts +15 -0
  31. package/dist/FirstResultReader.d.ts +19 -0
  32. package/dist/HashsetOptimizedReadonlyEnrichmentStrategy.d.ts +9 -0
  33. package/dist/IBulkWriteStrategy.d.ts +12 -0
  34. package/dist/ICRUDRepository.d.ts +12 -0
  35. package/dist/ICRUDRepositoryFactory.d.ts +7 -0
  36. package/dist/ICommand.d.ts +20 -0
  37. package/dist/ICommandMiddleware.d.ts +12 -0
  38. package/dist/IConnection.d.ts +12 -0
  39. package/dist/IDatasource.d.ts +18 -0
  40. package/dist/IDatasourceFactory.d.ts +5 -0
  41. package/dist/IDriver.d.ts +19 -0
  42. package/dist/IEnriched.d.ts +6 -0
  43. package/dist/IReader.d.ts +8 -0
  44. package/dist/IReadonlyEnrichmentStrategy.d.ts +7 -0
  45. package/dist/IReadonlyRepository.d.ts +11 -0
  46. package/dist/IRepository.d.ts +4 -0
  47. package/dist/IRepositoryFactory.d.ts +7 -0
  48. package/dist/IRepositoryTree.d.ts +4 -0
  49. package/dist/IRepositoryTreeNode.d.ts +7 -0
  50. package/dist/ITransaction.d.ts +8 -0
  51. package/dist/IUnitOfWork.d.ts +5 -0
  52. package/dist/IWriteEnrichmentStrategy.d.ts +7 -0
  53. package/dist/Information.d.ts +5 -0
  54. package/dist/IsolationLevel.d.ts +7 -0
  55. package/dist/LazyWriteEnrichmentStrategy.d.ts +4 -0
  56. package/dist/NestedToObjectEnrichmentStrategy.d.ts +10 -0
  57. package/dist/Parameter.d.ts +7 -0
  58. package/dist/ParameterDirection.d.ts +7 -0
  59. package/dist/ProviderCatalog.d.ts +7 -0
  60. package/dist/ProviderNotImplementedError.d.ts +4 -0
  61. package/dist/ProviderNotInstalledError.d.ts +4 -0
  62. package/dist/ReadonlyRepository.d.ts +59 -0
  63. package/dist/ReadonlyRepositoryBuilder.d.ts +12 -0
  64. package/dist/ReadonlyRepositoryMappingOptions.d.ts +14 -0
  65. package/dist/ReadonlyRepositoryStatements.d.ts +8 -0
  66. package/dist/RepositoryAccess.d.ts +11 -0
  67. package/dist/RepositoryFactory.d.ts +23 -0
  68. package/dist/RepositoryNotRegisteredError.d.ts +4 -0
  69. package/dist/RepositoryTree.d.ts +6 -0
  70. package/dist/RepositoryTreeNode.d.ts +9 -0
  71. package/dist/Response.d.ts +7 -0
  72. package/dist/Row.d.ts +2 -0
  73. package/dist/SingleCommandIBulkWriteStrategy.d.ts +11 -0
  74. package/dist/StatementMappers.d.ts +16 -0
  75. package/dist/StoredEnrichment.d.ts +11 -0
  76. package/dist/StoredProcedureBulkWriteStrategy.d.ts +27 -0
  77. package/dist/StreamingReader.d.ts +16 -0
  78. package/dist/UnitOfWorkTransaction.d.ts +12 -0
  79. package/dist/UpdateEnrichmentStrategy.d.ts +18 -0
  80. package/dist/WriteMode.d.ts +1 -0
  81. package/dist/builders/Field.d.ts +5 -0
  82. package/dist/builders/Scalar.d.ts +1 -0
  83. package/dist/builders/index.d.ts +2 -0
  84. package/dist/collectAsync.d.ts +1 -0
  85. package/dist/converters/Cell.d.ts +2 -0
  86. package/dist/converters/ChangeCasingConverter.d.ts +7 -0
  87. package/dist/converters/Constructable.d.ts +1 -0
  88. package/dist/converters/MetaDataRowTypeConverter.d.ts +14 -0
  89. package/dist/converters/PluralizerConverter.d.ts +4 -0
  90. package/dist/converters/RegexConverter.d.ts +7 -0
  91. package/dist/converters/ReplaceConverter.d.ts +7 -0
  92. package/dist/converters/RowTypeConverter.d.ts +10 -0
  93. package/dist/converters/ToLowerCaseConverter.d.ts +4 -0
  94. package/dist/converters/ToUpperCaseConverter.d.ts +4 -0
  95. package/dist/converters/TypeConverter.d.ts +5 -0
  96. package/dist/createCRUDRepositoryOptions.d.ts +7 -0
  97. package/dist/createReadonlyRepositoryMappingOptions.d.ts +6 -0
  98. package/dist/dotEnv.d.ts +5 -0
  99. package/dist/index.d.ts +119 -0
  100. package/dist/mappers/ChangeCasingMapper.d.ts +9 -0
  101. package/dist/mappers/DictionaryMapper.d.ts +8 -0
  102. package/dist/mappers/FlatToNestedMapper.d.ts +20 -0
  103. package/dist/mappers/IFlatToNestedMapper.d.ts +6 -0
  104. package/dist/mappers/IMapper.d.ts +4 -0
  105. package/dist/mappers/IdentityMapper.d.ts +5 -0
  106. package/dist/mappers/PluralizerMapper.d.ts +6 -0
  107. package/dist/mappers/RowTypeMapper.d.ts +6 -0
  108. package/dist/mappers/TransformConverterMapper.d.ts +5 -0
  109. package/dist/mappers/TransformMapper.d.ts +6 -0
  110. package/dist/mappers/TypeMap.d.ts +8 -0
  111. package/dist/mappers/TypeMapGroup.d.ts +5 -0
  112. package/dist/mocks/index.d.ts +9 -0
  113. package/dist/mocks/mock-command.d.ts +28 -0
  114. package/dist/mocks/mock-connection.d.ts +22 -0
  115. package/dist/mocks/mock-datasource.d.ts +24 -0
  116. package/dist/mocks/mock-driver.d.ts +15 -0
  117. package/dist/mocks/mock-reader.d.ts +14 -0
  118. package/dist/mocks/mock-repository.d.ts +42 -0
  119. package/dist/mocks/mock-select-statement.d.ts +10 -0
  120. package/dist/mocks/mock-transaction.d.ts +16 -0
  121. package/dist/mocks/mock-where.d.ts +8 -0
  122. package/dist/parametersToRecord.d.ts +2 -0
  123. package/dist/readerToAsyncIterable.d.ts +2 -0
  124. package/dist/splitStatements.d.ts +1 -0
  125. package/dist/statementParameters.d.ts +1 -0
  126. package/dist/statementUsesParameter.d.ts +1 -0
  127. package/dist/statements/Aggregate.d.ts +6 -0
  128. package/dist/statements/ArrayExpression.d.ts +5 -0
  129. package/dist/statements/BulkDeleteStatement.d.ts +11 -0
  130. package/dist/statements/BulkDeleteStatementTextRenderer.d.ts +4 -0
  131. package/dist/statements/BulkInsertStatement.d.ts +12 -0
  132. package/dist/statements/BulkInsertStatementTextRenderer.d.ts +4 -0
  133. package/dist/statements/BulkUpdateStatement.d.ts +16 -0
  134. package/dist/statements/BulkUpdateStatementTextRenderer.d.ts +8 -0
  135. package/dist/statements/CheckConstraint.d.ts +7 -0
  136. package/dist/statements/Cmp.d.ts +9 -0
  137. package/dist/statements/Column.d.ts +9 -0
  138. package/dist/statements/ColumnDefault.d.ts +5 -0
  139. package/dist/statements/Condition.d.ts +3 -0
  140. package/dist/statements/ConditionRenderer.d.ts +12 -0
  141. package/dist/statements/CreateIndexStatement.d.ts +10 -0
  142. package/dist/statements/CreateIndexStatementTextRenderer.d.ts +5 -0
  143. package/dist/statements/CreateTableStatement.d.ts +11 -0
  144. package/dist/statements/CreateTableStatementTextRenderer.d.ts +18 -0
  145. package/dist/statements/DefaultStatementTextRenderer.d.ts +5 -0
  146. package/dist/statements/DeleteStatement.d.ts +9 -0
  147. package/dist/statements/DeleteStatementTextRenderer.d.ts +7 -0
  148. package/dist/statements/ExecuteStoredProcedureStatement.d.ts +9 -0
  149. package/dist/statements/ExecuteStoredProcedureStatementTextRenderer.d.ts +4 -0
  150. package/dist/statements/ExpressionEvaluator.d.ts +5 -0
  151. package/dist/statements/ExpressionRenderer.d.ts +8 -0
  152. package/dist/statements/ForeignKey.d.ts +19 -0
  153. package/dist/statements/IBulkDeleteStatement.d.ts +3 -0
  154. package/dist/statements/IBulkInsertStatement.d.ts +3 -0
  155. package/dist/statements/IBulkUpdateStatement.d.ts +3 -0
  156. package/dist/statements/ICondition.d.ts +4 -0
  157. package/dist/statements/IConditionVisitor.d.ts +6 -0
  158. package/dist/statements/ICreateIndexStatement.d.ts +3 -0
  159. package/dist/statements/ICreateTableStatement.d.ts +3 -0
  160. package/dist/statements/IDeleteStatement.d.ts +5 -0
  161. package/dist/statements/IExecuteStoredProcedureStatement.d.ts +3 -0
  162. package/dist/statements/IExpression.d.ts +2 -0
  163. package/dist/statements/IInsertStatement.d.ts +3 -0
  164. package/dist/statements/IReturnStatement.d.ts +3 -0
  165. package/dist/statements/ISelectStatement.d.ts +5 -0
  166. package/dist/statements/IStatement.d.ts +4 -0
  167. package/dist/statements/IStatementVisitor.d.ts +26 -0
  168. package/dist/statements/ITableConstraint.d.ts +5 -0
  169. package/dist/statements/IUpdateStatement.d.ts +5 -0
  170. package/dist/statements/IWhere.d.ts +6 -0
  171. package/dist/statements/Identifier.d.ts +5 -0
  172. package/dist/statements/InsertStatement.d.ts +9 -0
  173. package/dist/statements/InsertStatementTextRenderer.d.ts +4 -0
  174. package/dist/statements/Join.d.ts +14 -0
  175. package/dist/statements/Literal.d.ts +6 -0
  176. package/dist/statements/Native.d.ts +5 -0
  177. package/dist/statements/NotNull.d.ts +4 -0
  178. package/dist/statements/Operator.d.ts +107 -0
  179. package/dist/statements/OrderBy.d.ts +10 -0
  180. package/dist/statements/PrimaryKey.d.ts +7 -0
  181. package/dist/statements/ReturnStatement.d.ts +9 -0
  182. package/dist/statements/ReturnStatementTextRenderer.d.ts +4 -0
  183. package/dist/statements/SelectInsertedIdStatement.d.ts +8 -0
  184. package/dist/statements/SelectInsertedIdStatementTextRenderer.d.ts +4 -0
  185. package/dist/statements/SelectStatement.d.ts +20 -0
  186. package/dist/statements/SelectStatementOptions.d.ts +15 -0
  187. package/dist/statements/SelectStatementTextRenderer.d.ts +19 -0
  188. package/dist/statements/StatementEvaluator.d.ts +4 -0
  189. package/dist/statements/StatementParser.d.ts +4 -0
  190. package/dist/statements/StatementRenderer.d.ts +42 -0
  191. package/dist/statements/StatementTextRenderer.d.ts +14 -0
  192. package/dist/statements/Subquery.d.ts +6 -0
  193. package/dist/statements/UniqueConstraint.d.ts +7 -0
  194. package/dist/statements/UpdateStatement.d.ts +14 -0
  195. package/dist/statements/UpdateStatementTextRenderer.d.ts +14 -0
  196. package/dist/statements/Where.d.ts +16 -0
  197. package/dist/statements/WhereText.d.ts +8 -0
  198. package/dist/statements/index.d.ts +75 -0
  199. package/dist/stubs/StubCommand.d.ts +15 -0
  200. package/dist/stubs/StubConnection.d.ts +13 -0
  201. package/dist/stubs/StubDatasource.d.ts +20 -0
  202. package/dist/stubs/StubReader.d.ts +11 -0
  203. package/dist/stubs/StubRepository.d.ts +22 -0
  204. package/dist/stubs/StubTransaction.d.ts +10 -0
  205. package/dist/stubs/createStubDatasource.d.ts +2 -0
  206. package/dist/stubs/index.d.ts +7 -0
  207. package/dist/stubs/notImplemented.d.ts +1 -0
  208. package/package.json +14 -6
  209. package/src/ArrayReader.test.ts +23 -0
  210. package/src/BulkCRUDRepository.test.ts +183 -0
  211. package/src/BulkWriteStrategy.test.ts +293 -0
  212. package/src/CRUDRepository.test.ts +420 -0
  213. package/src/CRUDRepository.ts +1 -1
  214. package/src/CRUDRepositoryOptions.test.ts +76 -0
  215. package/src/Command.test.ts +105 -0
  216. package/src/CommandMiddlewareHost.test.ts +98 -0
  217. package/src/Connection.test.ts +34 -0
  218. package/src/ConsoleCommandMiddleware.test.ts +149 -0
  219. package/src/Datasource.test.ts +63 -0
  220. package/src/DatasourceError.test.ts +10 -0
  221. package/src/DatasourceFactory.test.ts +159 -0
  222. package/src/DatasourceUrlParser.test.ts +173 -0
  223. package/src/ExpectConsoleMiddleware.test.ts +79 -0
  224. package/src/FirstResultReader.test.ts +43 -0
  225. package/src/IsolationLevel.test.ts +13 -0
  226. package/src/ProviderCatalog.test.ts +110 -0
  227. package/src/ProviderNotImplementedError.test.ts +11 -0
  228. package/src/ProviderNotInstalledError.test.ts +11 -0
  229. package/src/ReadonlyRepository.test.ts +406 -0
  230. package/src/RepositoryFactory.test.ts +94 -0
  231. package/src/StatementMappers.test.ts +221 -0
  232. package/src/StreamingReader.test.ts +126 -0
  233. package/src/Transaction.test.ts +37 -0
  234. package/src/UnitOfWorkTransaction.test.ts +43 -0
  235. package/src/UserViewCRUDRepository.test.ts +323 -0
  236. package/src/builders/builders.test.ts +404 -0
  237. package/src/converters/ChangeCasingConverter.test.ts +34 -0
  238. package/src/converters/PluralizerConverter.test.ts +43 -0
  239. package/src/converters/RegexConverter.test.ts +11 -0
  240. package/src/converters/ReplaceConverter.test.ts +9 -0
  241. package/src/converters/RowTypeConverter.test.ts +79 -0
  242. package/src/converters/ToLowerCaseConverter.test.ts +9 -0
  243. package/src/converters/ToUpperCaseConverter.test.ts +9 -0
  244. package/src/dotEnv.test.ts +21 -0
  245. package/src/edgeCases.test.ts +485 -0
  246. package/src/mappers/ChangeCasingMapper.test.ts +32 -0
  247. package/src/mappers/DictionaryMapper.test.ts +69 -0
  248. package/src/mappers/FlatToNestedMapper.test.ts +269 -0
  249. package/src/mappers/IdentityMapper.test.ts +12 -0
  250. package/src/mappers/PluralizerMapper.test.ts +40 -0
  251. package/src/mappers/RowTypeMapper.test.ts +12 -0
  252. package/src/mappers/TransformConverterMapper.test.ts +181 -0
  253. package/src/mappers/transformMapper.test.ts +66 -0
  254. package/src/mocks/MockCommand.test.ts +75 -0
  255. package/src/mocks/MockConnection.test.ts +34 -0
  256. package/src/mocks/MockDatasource.test.ts +40 -0
  257. package/src/mocks/MockReader.test.ts +17 -0
  258. package/src/mocks/MockRepository.test.ts +32 -0
  259. package/src/mocks/MockSelectStatement.test.ts +11 -0
  260. package/src/mocks/MockTransaction.test.ts +17 -0
  261. package/src/mocks/MockWhere.test.ts +11 -0
  262. package/src/parametersToRecord.test.ts +19 -0
  263. package/src/public-surface.test.ts +23 -0
  264. package/src/readWithWhereClauseAndCustomFlatToNestedObjectMappingOptions.test.ts +126 -0
  265. package/src/readerToAsyncIterable.test.ts +39 -0
  266. package/src/repository.test.ts +410 -0
  267. package/src/repository.type.test.ts +29 -0
  268. package/src/statements/SelectInsertedIdStatement.test.ts +11 -0
  269. package/src/statements/StatementCompile.test.ts +231 -0
  270. package/src/statements/StatementParser.test.ts +304 -0
  271. package/src/statements/index.ts +1 -1
  272. package/src/stubs/StubDatasource.test.ts +99 -0
  273. package/src/tests/contact/Address.ts +14 -0
  274. package/src/tests/contact/AddressType.ts +6 -0
  275. package/src/tests/contact/Base.ts +7 -0
  276. package/src/tests/contact/Contact.ts +12 -0
  277. package/src/tests/contact/ContactBase.ts +8 -0
  278. package/src/tests/contact/ContactChangeLog.ts +8 -0
  279. package/src/tests/contact/ContactGroup.ts +6 -0
  280. package/src/tests/contact/ContactGroupBase.ts +6 -0
  281. package/src/tests/contact/ContactGroupMember.ts +6 -0
  282. package/src/tests/contact/ContactSource.ts +6 -0
  283. package/src/tests/contact/ContactType.ts +6 -0
  284. package/src/tests/contact/ContactsService.test.ts +118 -0
  285. package/src/tests/contact/ContactsService.ts +32 -0
  286. package/src/tests/contact/ImportContactRequest.ts +4 -0
  287. package/src/tests/contact/ImportContactResult.ts +5 -0
  288. package/src/tests/contact/LegacyContact.ts +7 -0
  289. package/src/tests/contact/LegacyMigrationResult.ts +5 -0
  290. package/src/tests/contact/Phone.ts +9 -0
  291. package/src/tests/contact/PhoneType.ts +6 -0
  292. package/src/tests/contact/asContactsView.ts +63 -0
  293. package/src/tests/contact/contactColumns.ts +40 -0
  294. package/src/tests/contact/contactLookupIds.ts +32 -0
  295. package/src/tests/contact/contactLookups.ts +6 -0
  296. package/src/tests/contact/contactsParity.ts +63 -0
  297. package/src/tests/contact/contactsServiceOf.ts +38 -0
  298. package/src/tests/contact/contactsView.ts +31 -0
  299. package/src/tests/contact/expectContactsView.ts +23 -0
  300. package/src/tests/contact/extraContact.ts +61 -0
  301. package/src/tests/contact/logMapped.ts +5 -0
  302. package/src/tests/contact/seedContacts.ts +31 -0
@@ -0,0 +1,40 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ MockCommand,
4
+ MockConnection,
5
+ MockDatasource,
6
+ MockRepository,
7
+ Native,
8
+ untyped,
9
+ } from "../index.ts";
10
+
11
+ describe("MockDatasource", () => {
12
+ it("builds commands and repositories from a mock datasource", async () => {
13
+ const ds = new MockDatasource();
14
+ expect(ds.provider).toBe("mock");
15
+ expect(await ds.createConnection()).toBe(ds.connection);
16
+ const mockCommand = await ds.createCommand();
17
+ expect(mockCommand).toBeInstanceOf(MockCommand);
18
+ await mockCommand.executeNative(new Native(""));
19
+ await mockCommand.executeReaderNative(new Native(""));
20
+ const provided = new MockConnection();
21
+ expect((await ds.createCommand(provided)).connection).toBe(provided);
22
+ expect(ds.createRepository(untyped(), provided)).toBeInstanceOf(MockRepository);
23
+ expect(ds.createRepository(untyped())).toBeInstanceOf(MockRepository);
24
+
25
+ await ds.connection.close();
26
+ ds.command = new MockCommand(ds.connection);
27
+ ds.repository = new MockRepository(ds.connection);
28
+ expect(await ds.createCommand()).toBe(ds.command);
29
+ await expect(ds.createCommand()).rejects.toThrow("Connection is already open");
30
+ expect(ds.createRepository(untyped())).toBe(ds.repository);
31
+ expect(ds.createReadonlyRepository(untyped())).toBe(ds.repository);
32
+
33
+ const named = new MockDatasource("custom");
34
+ expect(named.provider).toBe("custom");
35
+ const customRepo = new MockRepository(named.connection);
36
+ named.repositories.register("Item", "items", () => customRepo, () => customRepo);
37
+ expect(named.createRepository("items")).toBe(customRepo);
38
+ expect(named.createReadonlyRepository("Item")).toBe(customRepo);
39
+ });
40
+ });
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { MockReader } from "../index.ts";
3
+
4
+ describe("MockReader", () => {
5
+ it("walks mock reader rows and errors", async () => {
6
+ const reader = new MockReader(["x"]);
7
+ expect(await reader.next()).toBe(true);
8
+ expect(reader.current).toBe("x");
9
+ expect(await reader.next()).toBe(false);
10
+ expect(await reader.nextResult()).toBe(false);
11
+ expect(await Array.fromAsync(new MockReader(["x"]).read())).toEqual(["x"]);
12
+ await reader.dispose();
13
+ await reader[Symbol.asyncDispose]();
14
+ reader.nextError = new Error("next");
15
+ await expect(reader.next()).rejects.toThrow("next");
16
+ });
17
+ });
@@ -0,0 +1,32 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { collectAsync, MockConnection, MockSelectStatement, MockRepository, MockWhere } from "../index.ts";
3
+
4
+ describe("MockRepository", () => {
5
+ it("records repository CRUD and errors", async () => {
6
+ const repo = new MockRepository<{ id: number }>(new MockConnection());
7
+ expect(await repo.readSingle()).toBeUndefined();
8
+ repo.items = [{ id: 1 }, { id: 2 }];
9
+ expect(await repo.readSingle(new MockSelectStatement("id=1"))).toEqual({ id: 1 });
10
+ expect(await collectAsync(repo.read())).toEqual([{ id: 1 }, { id: 2 }]);
11
+ expect(await collectAsync(repo.read(new MockSelectStatement("all")))).toHaveLength(2);
12
+ expect(await repo.readSingle(new MockWhere("id=1"))).toEqual({ id: 1 });
13
+ expect(await collectAsync(repo.read(new MockWhere("all")))).toHaveLength(2);
14
+ expect(await repo.readSingleById(1)).toEqual({ id: 1 });
15
+ expect(await repo.create({ id: 3 })).toEqual({ id: 3 });
16
+ expect(
17
+ (await repo.update({ id: 3 }, new MockWhere("id=3"))).rowsAffected,
18
+ ).toBe(1);
19
+ expect((await repo.delete({ id: 3 })).rowsAffected).toBe(1);
20
+
21
+ repo.readSingleError = new Error("gs");
22
+ await expect(repo.readSingle()).rejects.toThrow("gs");
23
+ repo.readError = new Error("g");
24
+ await expect(collectAsync(repo.read())).rejects.toThrow("g");
25
+ repo.addError = new Error("ad");
26
+ await expect(repo.create({ id: 0 })).rejects.toThrow("ad");
27
+ repo.updateError = new Error("up");
28
+ await expect(repo.update({ id: 0 })).rejects.toThrow("up");
29
+ repo.deleteError = new Error("del");
30
+ await expect(repo.delete({ id: 0 })).rejects.toThrow("del");
31
+ });
32
+ });
@@ -0,0 +1,11 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { DefaultStatementTextRenderer, MockSelectStatement } from "../index.ts";
3
+
4
+ describe("MockSelectStatement", () => {
5
+ it("tracks accept calls", () => {
6
+ const query = new MockSelectStatement("q");
7
+ expect(query.accept({ visit: () => "" })).toBe("q");
8
+ expect(query.acceptCalls).toBe(1);
9
+ expect(DefaultStatementTextRenderer.instance.render(query)).toBe("q");
10
+ });
11
+ });
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { MockConnection, MockTransaction } from "../index.ts";
3
+
4
+ describe("MockTransaction", () => {
5
+ it("records transaction commit and abort", async () => {
6
+ const connection = new MockConnection();
7
+ const txn = new MockTransaction(connection);
8
+ await txn.commit();
9
+ expect(txn.committed).toBe(true);
10
+ await txn.abort();
11
+ expect(txn.aborted).toBe(true);
12
+ txn.commitError = new Error("c");
13
+ await expect(txn.commit()).rejects.toThrow("c");
14
+ txn.abortError = new Error("a");
15
+ await expect(txn.abort()).rejects.toThrow("a");
16
+ });
17
+ });
@@ -0,0 +1,11 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { DefaultStatementTextRenderer, MockWhere } from "../index.ts";
3
+
4
+ describe("MockWhere", () => {
5
+ it("tracks accept calls", () => {
6
+ const where = new MockWhere("w");
7
+ expect(where.accept({ visit: () => "" })).toBe("w");
8
+ expect(where.acceptCalls).toBe(1);
9
+ expect(DefaultStatementTextRenderer.instance.render(where)).toBe("w");
10
+ });
11
+ });
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { parametersToRecord } from "./index.ts";
3
+
4
+ describe("parametersToRecord", () => {
5
+ it("returns an empty record when parameters are omitted", () => {
6
+ expect(parametersToRecord()).toEqual({});
7
+ expect(parametersToRecord(null)).toEqual({});
8
+ expect(parametersToRecord(undefined)).toEqual({});
9
+ });
10
+
11
+ it("maps names to values", () => {
12
+ expect(
13
+ parametersToRecord([
14
+ { name: "id", value: 1 },
15
+ { name: "label", value: "a" },
16
+ ]),
17
+ ).toEqual({ id: 1, label: "a" });
18
+ });
19
+ });
@@ -0,0 +1,23 @@
1
+ import { readdirSync, readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { describe, expect, it } from "vitest";
5
+
6
+ const providers = join(dirname(fileURLToPath(import.meta.url)), "../../providers");
7
+
8
+ describe("provider public surface", () => {
9
+ it("exports only the provider", () => {
10
+ const names = readdirSync(providers, { withFileTypes: true })
11
+ .filter((entry) => entry.isDirectory() && entry.name !== "node_modules")
12
+ .map((entry) => entry.name);
13
+ expect(names.length).toBeGreaterThanOrEqual(11);
14
+ for (const name of names) {
15
+ const source = readFileSync(join(providers, name, "src/index.ts"), "utf8");
16
+ const match = source.match(
17
+ /^export \{ ([A-Za-z0-9]+) \} from "\.\/\1\.ts";\n$/,
18
+ );
19
+ expect(match, name).not.toBeNull();
20
+ expect(match?.[1]?.endsWith("Driver"), name).toBe(true);
21
+ }
22
+ });
23
+ });
@@ -0,0 +1,126 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { MemoryDriver } from "@datasources/memory";
3
+ import { collectAsync } from "./collectAsync.ts";
4
+ import { CRUDRepository } from "./CRUDRepository.ts";
5
+ import { NestedToObjectEnrichmentStrategy } from "./NestedToObjectEnrichmentStrategy.ts";
6
+ import { ChangeCasingMapper } from "./mappers/ChangeCasingMapper.ts";
7
+ import { DictionaryMapper } from "./mappers/DictionaryMapper.ts";
8
+ import type { IMapper } from "./mappers/IMapper.ts";
9
+ import { TransformMapper } from "./mappers/TransformMapper.ts";
10
+ import type { IConnection } from "./IConnection.ts";
11
+ import type { Scalar } from "./builders/Scalar.ts";
12
+ import { MockCommand } from "./mocks/mock-command.ts";
13
+ import { MockConnection } from "./mocks/mock-connection.ts";
14
+ import { MockReader } from "./mocks/mock-reader.ts";
15
+ import { Join, Operator, SelectStatement, Where } from "./statements/index.ts";
16
+
17
+ describe("readWithWhereClauseAndCustomFlatToNestedObjectMappingOptions", () => {
18
+ it("read with where clause and custom flat to nested object mapping options", async () => {
19
+ class UserType {
20
+ Id = 0;
21
+ Name = "";
22
+ }
23
+
24
+ class Parent {
25
+ Id = 0;
26
+ Type = new UserType();
27
+ TypeName = "";
28
+ Children: Child[] = [];
29
+ }
30
+
31
+ class Child {
32
+ Id = 0;
33
+ ParentId = 0;
34
+ Label = "";
35
+ }
36
+
37
+ type Seed = Record<string, Scalar>;
38
+
39
+ const snake = new ChangeCasingMapper("pascalCase", "snakeCase");
40
+ const references = new DictionaryMapper<string>([["Type", "type_id"]]);
41
+ const columns: IMapper<string, string> = new TransformMapper(
42
+ (name) => {
43
+ const mapped = references.map(name);
44
+ return mapped !== name ? mapped : snake.map(name);
45
+ },
46
+ (name) => {
47
+ const from = references.reverseMap(name);
48
+ return from !== name ? from : snake.reverseMap(name);
49
+ },
50
+ );
51
+
52
+ const joinEntity = new DictionaryMapper([
53
+ ["Parent", "parent"],
54
+ ["Child", "child"],
55
+ ]);
56
+
57
+ const setup = async (): Promise<IConnection> => {
58
+ const connection = new MemoryDriver().connection();
59
+ await connection.open();
60
+ return connection;
61
+ };
62
+
63
+ const typesRepo = (connection: IConnection) =>
64
+ new CRUDRepository(connection, { type: UserType, ids: ["Id"], propertyMappings: columns });
65
+
66
+ const parentsRepo = (connection: IConnection) =>
67
+ new CRUDRepository(connection, { type: Parent, ids: ["Id"], propertyMappings: columns });
68
+
69
+ const connection = await setup();
70
+ const types = typesRepo(connection);
71
+ const type = await types.create(Object.assign(new UserType(), { Name: "person" }));
72
+ const parents = parentsRepo(connection);
73
+ parents.addEnriched(
74
+ { destinationProperty: "TypeName", sourceProperty: "Type", relatedKey: "Id", relatedProperty: "Name" },
75
+ types,
76
+ );
77
+ await parents.create(Object.assign(new Parent(), { Type: Object.assign(new UserType(), { Id: type.Id }) }));
78
+ const enriched = await parents.readSingle();
79
+
80
+ const row1: Seed = { Id: 1, TypeName: "person", ChildId: 10, Label: "a" };
81
+ const row2: Seed = { Id: 1, TypeName: "person", ChildId: 11, Label: "b" };
82
+ const mockConnection = new MockConnection({ provider: "memory" });
83
+ const command = new MockCommand(mockConnection);
84
+ mockConnection.command = command;
85
+ const joinParents = parentsRepo(mockConnection);
86
+ joinParents.addEnriched(
87
+ { destinationProperty: "TypeName", sourceProperty: "Type", relatedKey: "Id", relatedProperty: "Name" },
88
+ types,
89
+ );
90
+ joinParents.addEnriched(
91
+ { destinationProperty: "Children", sourceProperty: "Id", relatedKey: "ParentId", type: "list" },
92
+ joinParents,
93
+ new NestedToObjectEnrichmentStrategy<Parent>({
94
+ key: "Id",
95
+ fields: {
96
+ Id: "Id",
97
+ TypeName: "TypeName",
98
+ Children: {
99
+ key: "ChildId",
100
+ fields: { Id: "ChildId", Label: "Label" },
101
+ },
102
+ },
103
+ }),
104
+ );
105
+ const join = new SelectStatement({
106
+ table: "Parent",
107
+ fields: [
108
+ "Parent.Id AS Id",
109
+ "Parent.TypeName AS TypeName",
110
+ "Child.Id AS ChildId",
111
+ "Child.Label AS Label",
112
+ ],
113
+ joins: [Join.left("Child", "Parent.Id", "Child.ParentId")],
114
+ where: new Where(new Operator.Equals("Parent.Id", 1)),
115
+ });
116
+ command.reader = new MockReader([row1, row2]);
117
+ const items = await collectAsync(
118
+ joinParents.read(join, undefined, { entityMapper: joinEntity }),
119
+ );
120
+ expect(enriched?.TypeName).toBe("person");
121
+ expect(items).toHaveLength(1);
122
+ expect(items[0]?.Id).toBe(1);
123
+ expect(items[0]?.TypeName).toBe("person");
124
+ expect(items[0]?.Children.map((child) => child.Label)).toEqual(["a", "b"]);
125
+ });
126
+ });
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { ArrayReader, collectAsync, readerToAsyncIterable, type IReader } from "./index.ts";
3
+
4
+ describe("readerToAsyncIterable", () => {
5
+ it("converts a reader to an async iterable", async () => {
6
+ const items = await collectAsync(
7
+ readerToAsyncIterable(new ArrayReader(["a", "b"])),
8
+ );
9
+ expect(items).toEqual(["a", "b"]);
10
+ expect(await collectAsync(readerToAsyncIterable(new ArrayReader([])))).toEqual(
11
+ [],
12
+ );
13
+ });
14
+
15
+ it("skips a defined-next row whose current is undefined", async () => {
16
+ const reader: IReader<string> = {
17
+ current: undefined,
18
+ read() {
19
+ return readerToAsyncIterable(this);
20
+ },
21
+ async nextResult() {
22
+ return false;
23
+ },
24
+ async dispose() {},
25
+ async [Symbol.asyncDispose]() {
26
+ await this.dispose();
27
+ },
28
+ async next() {
29
+ if (this.current === undefined && (this as { once?: boolean }).once) {
30
+ return false;
31
+ }
32
+ (this as { once?: boolean }).once = true;
33
+ this.current = undefined;
34
+ return true;
35
+ },
36
+ };
37
+ expect(await collectAsync(readerToAsyncIterable(reader))).toEqual([]);
38
+ });
39
+ });