@deterministic-code/datasources 0.0.0-stage → 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 (508) 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 +24 -4
  209. package/src/ArrayReader.test.ts +23 -0
  210. package/src/ArrayReader.ts +32 -0
  211. package/src/BatchCommandIBulkWriteStrategy.ts +228 -0
  212. package/src/BuiltRepository.ts +17 -0
  213. package/src/BulkCRUDRepository.test.ts +183 -0
  214. package/src/BulkCRUDRepository.ts +84 -0
  215. package/src/BulkCommand.ts +6 -0
  216. package/src/BulkWriteEnrichment.ts +19 -0
  217. package/src/BulkWriteStrategy.test.ts +293 -0
  218. package/src/CRUDRepository.test.ts +420 -0
  219. package/src/CRUDRepository.ts +264 -0
  220. package/src/CRUDRepositoryBuilder.ts +53 -0
  221. package/src/CRUDRepositoryOptions.test.ts +76 -0
  222. package/src/CRUDRepositoryOptions.ts +8 -0
  223. package/src/CRUDRepositoryStatements.ts +43 -0
  224. package/src/CascadeDeleteEnrichmentStrategy.ts +51 -0
  225. package/src/CascadeDeleteUpdateEnrichmentStrategy.ts +28 -0
  226. package/src/Command.test.ts +105 -0
  227. package/src/CommandMiddlewareHost.test.ts +98 -0
  228. package/src/CommandMiddlewareHost.ts +113 -0
  229. package/src/Connection.test.ts +34 -0
  230. package/src/ConsoleCommandMiddleware.test.ts +149 -0
  231. package/src/ConsoleCommandMiddleware.ts +64 -0
  232. package/src/CreateEnrichmentStrategy.ts +82 -0
  233. package/src/Datasource.test.ts +63 -0
  234. package/src/Datasource.ts +152 -0
  235. package/src/DatasourceError.test.ts +10 -0
  236. package/src/DatasourceError.ts +6 -0
  237. package/src/DatasourceFactory.test.ts +159 -0
  238. package/src/DatasourceFactory.ts +86 -0
  239. package/src/DatasourceOptions.ts +1 -0
  240. package/src/DatasourceUrl.ts +37 -0
  241. package/src/DatasourceUrlParser.test.ts +173 -0
  242. package/src/DatasourceUrlParser.ts +188 -0
  243. package/src/DefaultCreateEnrichmentStrategy.ts +21 -0
  244. package/src/DefaultReadonlyEnrichmentStrategy.ts +164 -0
  245. package/src/DefaultUpdateEnrichmentStrategy.ts +40 -0
  246. package/src/DefaultWriteEnrichmentStrategy.ts +151 -0
  247. package/src/DeleteEnrichmentStrategy.ts +56 -0
  248. package/src/DriverLoader.ts +97 -0
  249. package/src/Enrichment.ts +15 -0
  250. package/src/EnrichmentPropertyType.ts +9 -0
  251. package/src/ExpectConsoleMiddleware.test.ts +79 -0
  252. package/src/ExpectConsoleMiddleware.ts +47 -0
  253. package/src/FirstResultReader.test.ts +43 -0
  254. package/src/FirstResultReader.ts +49 -0
  255. package/src/HashsetOptimizedReadonlyEnrichmentStrategy.ts +80 -0
  256. package/src/IBulkWriteStrategy.ts +13 -0
  257. package/src/ICRUDRepository.ts +13 -0
  258. package/src/ICRUDRepositoryFactory.ts +8 -0
  259. package/src/ICommand.ts +45 -0
  260. package/src/ICommandMiddleware.ts +20 -0
  261. package/src/IConnection.ts +13 -0
  262. package/src/IDatasource.ts +27 -0
  263. package/src/IDatasourceFactory.ts +6 -0
  264. package/src/IDriver.ts +24 -0
  265. package/src/IEnriched.ts +11 -0
  266. package/src/IReader.ts +8 -0
  267. package/src/IReadonlyEnrichmentStrategy.ts +19 -0
  268. package/src/IReadonlyRepository.ts +21 -0
  269. package/src/IRepository.ts +5 -0
  270. package/src/IRepositoryFactory.ts +8 -0
  271. package/src/IRepositoryTree.ts +5 -0
  272. package/src/IRepositoryTreeNode.ts +8 -0
  273. package/src/ITransaction.ts +9 -0
  274. package/src/IUnitOfWork.ts +5 -0
  275. package/src/IWriteEnrichmentStrategy.ts +8 -0
  276. package/src/Information.ts +5 -0
  277. package/src/IsolationLevel.test.ts +13 -0
  278. package/src/IsolationLevel.ts +8 -0
  279. package/src/LazyWriteEnrichmentStrategy.ts +5 -0
  280. package/src/NestedToObjectEnrichmentStrategy.ts +33 -0
  281. package/src/Parameter.ts +8 -0
  282. package/src/ParameterDirection.ts +9 -0
  283. package/src/ProviderCatalog.test.ts +110 -0
  284. package/src/ProviderCatalog.ts +21 -0
  285. package/src/ProviderNotImplementedError.test.ts +11 -0
  286. package/src/ProviderNotImplementedError.ts +9 -0
  287. package/src/ProviderNotInstalledError.test.ts +11 -0
  288. package/src/ProviderNotInstalledError.ts +9 -0
  289. package/src/ReadonlyRepository.test.ts +406 -0
  290. package/src/ReadonlyRepository.ts +276 -0
  291. package/src/ReadonlyRepositoryBuilder.ts +53 -0
  292. package/src/ReadonlyRepositoryMappingOptions.ts +15 -0
  293. package/src/ReadonlyRepositoryStatements.ts +13 -0
  294. package/src/RepositoryAccess.ts +14 -0
  295. package/src/RepositoryFactory.test.ts +94 -0
  296. package/src/RepositoryFactory.ts +115 -0
  297. package/src/RepositoryNotRegisteredError.ts +9 -0
  298. package/src/RepositoryTree.ts +6 -0
  299. package/src/RepositoryTreeNode.ts +11 -0
  300. package/src/Response.ts +15 -0
  301. package/src/Row.ts +3 -0
  302. package/src/SingleCommandIBulkWriteStrategy.ts +35 -0
  303. package/src/StatementMappers.test.ts +221 -0
  304. package/src/StatementMappers.ts +110 -0
  305. package/src/StoredEnrichment.ts +25 -0
  306. package/src/StoredProcedureBulkWriteStrategy.ts +164 -0
  307. package/src/StreamingReader.test.ts +126 -0
  308. package/src/StreamingReader.ts +64 -0
  309. package/src/Transaction.test.ts +37 -0
  310. package/src/UnitOfWorkTransaction.test.ts +43 -0
  311. package/src/UnitOfWorkTransaction.ts +50 -0
  312. package/src/UpdateEnrichmentStrategy.ts +97 -0
  313. package/src/UserViewCRUDRepository.test.ts +323 -0
  314. package/src/WriteMode.ts +1 -0
  315. package/src/builders/Field.ts +6 -0
  316. package/src/builders/Scalar.ts +1 -0
  317. package/src/builders/builders.test.ts +404 -0
  318. package/src/builders/index.ts +2 -0
  319. package/src/collectAsync.ts +7 -0
  320. package/src/converters/Cell.ts +10 -0
  321. package/src/converters/ChangeCasingConverter.test.ts +34 -0
  322. package/src/converters/ChangeCasingConverter.ts +59 -0
  323. package/src/converters/Constructable.ts +1 -0
  324. package/src/converters/MetaDataRowTypeConverter.ts +80 -0
  325. package/src/converters/PluralizerConverter.test.ts +43 -0
  326. package/src/converters/PluralizerConverter.ts +67 -0
  327. package/src/converters/RegexConverter.test.ts +11 -0
  328. package/src/converters/RegexConverter.ts +14 -0
  329. package/src/converters/ReplaceConverter.test.ts +9 -0
  330. package/src/converters/ReplaceConverter.ts +6 -0
  331. package/src/converters/RowTypeConverter.test.ts +79 -0
  332. package/src/converters/RowTypeConverter.ts +33 -0
  333. package/src/converters/ToLowerCaseConverter.test.ts +9 -0
  334. package/src/converters/ToLowerCaseConverter.ts +4 -0
  335. package/src/converters/ToUpperCaseConverter.test.ts +9 -0
  336. package/src/converters/ToUpperCaseConverter.ts +4 -0
  337. package/src/converters/TypeConverter.ts +6 -0
  338. package/src/createCRUDRepositoryOptions.ts +21 -0
  339. package/src/createReadonlyRepositoryMappingOptions.ts +26 -0
  340. package/src/dotEnv.test.ts +21 -0
  341. package/src/dotEnv.ts +16 -0
  342. package/src/edgeCases.test.ts +485 -0
  343. package/src/index.ts +222 -0
  344. package/src/mappers/ChangeCasingMapper.test.ts +32 -0
  345. package/src/mappers/ChangeCasingMapper.ts +15 -0
  346. package/src/mappers/DictionaryMapper.test.ts +69 -0
  347. package/src/mappers/DictionaryMapper.ts +16 -0
  348. package/src/mappers/FlatToNestedMapper.test.ts +269 -0
  349. package/src/mappers/FlatToNestedMapper.ts +127 -0
  350. package/src/mappers/IFlatToNestedMapper.ts +7 -0
  351. package/src/mappers/IMapper.ts +4 -0
  352. package/src/mappers/IdentityMapper.test.ts +12 -0
  353. package/src/mappers/IdentityMapper.ts +6 -0
  354. package/src/mappers/PluralizerMapper.test.ts +40 -0
  355. package/src/mappers/PluralizerMapper.ts +9 -0
  356. package/src/mappers/RowTypeMapper.test.ts +12 -0
  357. package/src/mappers/RowTypeMapper.ts +13 -0
  358. package/src/mappers/TransformConverterMapper.test.ts +181 -0
  359. package/src/mappers/TransformConverterMapper.ts +11 -0
  360. package/src/mappers/TransformMapper.ts +8 -0
  361. package/src/mappers/TypeMap.ts +10 -0
  362. package/src/mappers/TypeMapGroup.ts +6 -0
  363. package/src/mappers/transformMapper.test.ts +66 -0
  364. package/src/mocks/MockCommand.test.ts +75 -0
  365. package/src/mocks/MockConnection.test.ts +34 -0
  366. package/src/mocks/MockDatasource.test.ts +40 -0
  367. package/src/mocks/MockReader.test.ts +17 -0
  368. package/src/mocks/MockRepository.test.ts +32 -0
  369. package/src/mocks/MockSelectStatement.test.ts +11 -0
  370. package/src/mocks/MockTransaction.test.ts +17 -0
  371. package/src/mocks/MockWhere.test.ts +11 -0
  372. package/src/mocks/index.ts +9 -0
  373. package/src/mocks/mock-command.ts +66 -0
  374. package/src/mocks/mock-connection.ts +57 -0
  375. package/src/mocks/mock-datasource.ts +65 -0
  376. package/src/mocks/mock-driver.ts +27 -0
  377. package/src/mocks/mock-reader.ts +38 -0
  378. package/src/mocks/mock-repository.ts +91 -0
  379. package/src/mocks/mock-select-statement.ts +17 -0
  380. package/src/mocks/mock-transaction.ts +31 -0
  381. package/src/mocks/mock-where.ts +13 -0
  382. package/src/parametersToRecord.test.ts +19 -0
  383. package/src/parametersToRecord.ts +11 -0
  384. package/src/public-surface.test.ts +23 -0
  385. package/src/readWithWhereClauseAndCustomFlatToNestedObjectMappingOptions.test.ts +126 -0
  386. package/src/readerToAsyncIterable.test.ts +39 -0
  387. package/src/readerToAsyncIterable.ts +11 -0
  388. package/src/repository.test.ts +410 -0
  389. package/src/repository.type.test.ts +29 -0
  390. package/src/splitStatements.ts +99 -0
  391. package/src/statementParameters.ts +22 -0
  392. package/src/statementUsesParameter.ts +4 -0
  393. package/src/statements/Aggregate.ts +9 -0
  394. package/src/statements/ArrayExpression.ts +5 -0
  395. package/src/statements/BulkDeleteStatement.ts +18 -0
  396. package/src/statements/BulkDeleteStatementTextRenderer.ts +16 -0
  397. package/src/statements/BulkInsertStatement.ts +37 -0
  398. package/src/statements/BulkInsertStatementTextRenderer.ts +10 -0
  399. package/src/statements/BulkUpdateStatement.ts +24 -0
  400. package/src/statements/BulkUpdateStatementTextRenderer.ts +29 -0
  401. package/src/statements/CheckConstraint.ts +9 -0
  402. package/src/statements/Cmp.ts +12 -0
  403. package/src/statements/Column.ts +10 -0
  404. package/src/statements/ColumnDefault.ts +6 -0
  405. package/src/statements/Condition.ts +3 -0
  406. package/src/statements/ConditionRenderer.ts +17 -0
  407. package/src/statements/CreateIndexStatement.ts +18 -0
  408. package/src/statements/CreateIndexStatementTextRenderer.ts +11 -0
  409. package/src/statements/CreateTableStatement.ts +18 -0
  410. package/src/statements/CreateTableStatementTextRenderer.ts +92 -0
  411. package/src/statements/DefaultStatementTextRenderer.ts +9 -0
  412. package/src/statements/DeleteStatement.ts +15 -0
  413. package/src/statements/DeleteStatementTextRenderer.ts +12 -0
  414. package/src/statements/ExecuteStoredProcedureStatement.ts +15 -0
  415. package/src/statements/ExecuteStoredProcedureStatementTextRenderer.ts +15 -0
  416. package/src/statements/ExpressionEvaluator.ts +166 -0
  417. package/src/statements/ExpressionRenderer.ts +161 -0
  418. package/src/statements/ForeignKey.ts +23 -0
  419. package/src/statements/IBulkDeleteStatement.ts +3 -0
  420. package/src/statements/IBulkInsertStatement.ts +3 -0
  421. package/src/statements/IBulkUpdateStatement.ts +3 -0
  422. package/src/statements/ICondition.ts +5 -0
  423. package/src/statements/IConditionVisitor.ts +7 -0
  424. package/src/statements/ICreateIndexStatement.ts +3 -0
  425. package/src/statements/ICreateTableStatement.ts +3 -0
  426. package/src/statements/IDeleteStatement.ts +6 -0
  427. package/src/statements/IExecuteStoredProcedureStatement.ts +3 -0
  428. package/src/statements/IExpression.ts +1 -0
  429. package/src/statements/IInsertStatement.ts +3 -0
  430. package/src/statements/IReturnStatement.ts +3 -0
  431. package/src/statements/ISelectStatement.ts +6 -0
  432. package/src/statements/IStatement.ts +5 -0
  433. package/src/statements/IStatementVisitor.ts +27 -0
  434. package/src/statements/ITableConstraint.ts +6 -0
  435. package/src/statements/IUpdateStatement.ts +6 -0
  436. package/src/statements/IWhere.ts +7 -0
  437. package/src/statements/Identifier.ts +5 -0
  438. package/src/statements/InsertStatement.ts +15 -0
  439. package/src/statements/InsertStatementTextRenderer.ts +7 -0
  440. package/src/statements/Join.ts +26 -0
  441. package/src/statements/Literal.ts +6 -0
  442. package/src/statements/Native.ts +5 -0
  443. package/src/statements/NotNull.ts +3 -0
  444. package/src/statements/Operator.ts +234 -0
  445. package/src/statements/OrderBy.ts +19 -0
  446. package/src/statements/PrimaryKey.ts +9 -0
  447. package/src/statements/ReturnStatement.ts +15 -0
  448. package/src/statements/ReturnStatementTextRenderer.ts +15 -0
  449. package/src/statements/SelectInsertedIdStatement.test.ts +11 -0
  450. package/src/statements/SelectInsertedIdStatement.ts +11 -0
  451. package/src/statements/SelectInsertedIdStatementTextRenderer.ts +7 -0
  452. package/src/statements/SelectStatement.ts +34 -0
  453. package/src/statements/SelectStatementOptions.ts +16 -0
  454. package/src/statements/SelectStatementTextRenderer.ts +71 -0
  455. package/src/statements/StatementCompile.test.ts +231 -0
  456. package/src/statements/StatementEvaluator.ts +5 -0
  457. package/src/statements/StatementParser.test.ts +304 -0
  458. package/src/statements/StatementParser.ts +461 -0
  459. package/src/statements/StatementRenderer.ts +120 -0
  460. package/src/statements/StatementTextRenderer.ts +60 -0
  461. package/src/statements/Subquery.ts +6 -0
  462. package/src/statements/UniqueConstraint.ts +9 -0
  463. package/src/statements/UpdateStatement.ts +34 -0
  464. package/src/statements/UpdateStatementTextRenderer.ts +63 -0
  465. package/src/statements/Where.ts +250 -0
  466. package/src/statements/WhereText.ts +10 -0
  467. package/src/statements/index.ts +75 -0
  468. package/src/stubs/StubCommand.ts +30 -0
  469. package/src/stubs/StubConnection.ts +21 -0
  470. package/src/stubs/StubDatasource.test.ts +99 -0
  471. package/src/stubs/StubDatasource.ts +60 -0
  472. package/src/stubs/StubReader.ts +25 -0
  473. package/src/stubs/StubRepository.ts +42 -0
  474. package/src/stubs/StubTransaction.ts +17 -0
  475. package/src/stubs/createStubDatasource.ts +4 -0
  476. package/src/stubs/index.ts +7 -0
  477. package/src/stubs/notImplemented.ts +5 -0
  478. package/src/tests/contact/Address.ts +14 -0
  479. package/src/tests/contact/AddressType.ts +6 -0
  480. package/src/tests/contact/Base.ts +7 -0
  481. package/src/tests/contact/Contact.ts +12 -0
  482. package/src/tests/contact/ContactBase.ts +8 -0
  483. package/src/tests/contact/ContactChangeLog.ts +8 -0
  484. package/src/tests/contact/ContactGroup.ts +6 -0
  485. package/src/tests/contact/ContactGroupBase.ts +6 -0
  486. package/src/tests/contact/ContactGroupMember.ts +6 -0
  487. package/src/tests/contact/ContactSource.ts +6 -0
  488. package/src/tests/contact/ContactType.ts +6 -0
  489. package/src/tests/contact/ContactsService.test.ts +118 -0
  490. package/src/tests/contact/ContactsService.ts +32 -0
  491. package/src/tests/contact/ImportContactRequest.ts +4 -0
  492. package/src/tests/contact/ImportContactResult.ts +5 -0
  493. package/src/tests/contact/LegacyContact.ts +7 -0
  494. package/src/tests/contact/LegacyMigrationResult.ts +5 -0
  495. package/src/tests/contact/Phone.ts +9 -0
  496. package/src/tests/contact/PhoneType.ts +6 -0
  497. package/src/tests/contact/asContactsView.ts +63 -0
  498. package/src/tests/contact/contactColumns.ts +40 -0
  499. package/src/tests/contact/contactLookupIds.ts +32 -0
  500. package/src/tests/contact/contactLookups.ts +6 -0
  501. package/src/tests/contact/contactsParity.ts +63 -0
  502. package/src/tests/contact/contactsServiceOf.ts +38 -0
  503. package/src/tests/contact/contactsView.ts +31 -0
  504. package/src/tests/contact/expectContactsView.ts +23 -0
  505. package/src/tests/contact/extraContact.ts +61 -0
  506. package/src/tests/contact/logMapped.ts +5 -0
  507. package/src/tests/contact/seedContacts.ts +31 -0
  508. package/README.md +0 -3
@@ -0,0 +1,276 @@
1
+ import type { ICommand } from "./ICommand.ts";
2
+ import { executeReader } from "./ICommand.ts";
3
+ import type { ICommandMiddleware } from "./ICommandMiddleware.ts";
4
+ import type { IConnection } from "./IConnection.ts";
5
+ import { ExecuteStoredProcedureStatement } from "./statements/ExecuteStoredProcedureStatement.ts";
6
+ import type { Parameter } from "./Parameter.ts";
7
+ import type { ISelectStatement } from "./statements/ISelectStatement.ts";
8
+ import type { IStatement } from "./statements/IStatement.ts";
9
+ import type { IReadonlyRepository, ReadQuery } from "./IReadonlyRepository.ts";
10
+ import type { Row } from "./Row.ts";
11
+ import type { IWhere } from "./statements/IWhere.ts";
12
+ import { DatasourceError } from "./DatasourceError.ts";
13
+ import type { Cell, Cells } from "./converters/Cell.ts";
14
+ import type { Constructable } from "./converters/Constructable.ts";
15
+ import { MetaDataRowTypeConverter } from "./converters/MetaDataRowTypeConverter.ts";
16
+ import { SelectStatement } from "./statements/SelectStatement.ts";
17
+ import { createReadonlyRepositoryMappingOptions } from "./createReadonlyRepositoryMappingOptions.ts";
18
+ import type { ReadonlyRepositoryMappingOptions } from "./ReadonlyRepositoryMappingOptions.ts";
19
+ import type { BuiltRepository } from "./BuiltRepository.ts";
20
+ import { ReadonlyRepositoryBuilder } from "./ReadonlyRepositoryBuilder.ts";
21
+ import type { TypeConverter } from "./converters/TypeConverter.ts";
22
+ import type { IMapper } from "./mappers/IMapper.ts";
23
+ import { IdentityMapper } from "./mappers/IdentityMapper.ts";
24
+ import type { ReadonlyRepositoryStatements } from "./ReadonlyRepositoryStatements.ts";
25
+ import { StatementMappers } from "./StatementMappers.ts";
26
+ import { DefaultReadonlyEnrichmentStrategy } from "./DefaultReadonlyEnrichmentStrategy.ts";
27
+ import type { Enrichment } from "./Enrichment.ts";
28
+ import type { IEnriched } from "./IEnriched.ts";
29
+ import type { IReadonlyEnrichmentStrategy } from "./IReadonlyEnrichmentStrategy.ts";
30
+ import { StoredEnrichment } from "./StoredEnrichment.ts";
31
+
32
+ export const untyped = <T>(): Constructable<T> => Object as never as Constructable<T>;
33
+
34
+ export type Sourced<T> = { item: T; source?: Row };
35
+
36
+ const storedEnrichments = new WeakMap<object, StoredEnrichment[]>();
37
+
38
+ export const enrichmentsOf = (host: object): readonly StoredEnrichment[] | undefined =>
39
+ storedEnrichments.get(host);
40
+
41
+ export const isBuilt = <T>(
42
+ value: IConnection | BuiltRepository<T>,
43
+ ): value is BuiltRepository<T> =>
44
+ "statements" in value && "objectConverter" in value && "propertyMappings" in value;
45
+
46
+ export const builtOf = <T>(
47
+ typeOrConnectionOrBuilt: Constructable<T> | IConnection | BuiltRepository<T>,
48
+ connectionOrOptions?: IConnection | ReadonlyRepositoryMappingOptions<T>,
49
+ ): BuiltRepository<T> | undefined =>
50
+ typeof typeOrConnectionOrBuilt === "function"
51
+ ? connectionOrOptions === undefined
52
+ ? undefined
53
+ : new ReadonlyRepositoryBuilder<T>().parts(
54
+ connectionOrOptions as IConnection,
55
+ createReadonlyRepositoryMappingOptions(typeOrConnectionOrBuilt),
56
+ )
57
+ : isBuilt(typeOrConnectionOrBuilt)
58
+ ? typeOrConnectionOrBuilt
59
+ : new ReadonlyRepositoryBuilder<T>().parts(
60
+ typeOrConnectionOrBuilt,
61
+ connectionOrOptions as ReadonlyRepositoryMappingOptions<T>,
62
+ );
63
+
64
+ export class ReadonlyRepository<T> implements IReadonlyRepository<T>, IEnriched<T> {
65
+ readonly type: Constructable<T>;
66
+ private connection?: IConnection;
67
+ protected rowConverter?: TypeConverter<Cells, Cells>;
68
+ protected objectConverter?: TypeConverter<T, Cells>;
69
+ private entityMappers: IMapper<string, string> = new IdentityMapper();
70
+ private propertyMappers: IMapper<string, string> = new IdentityMapper();
71
+ private statementMappers = new StatementMappers(new IdentityMapper(), new IdentityMapper());
72
+ private readonlyStatements?: ReadonlyRepositoryStatements;
73
+ private readonly middlewares: ICommandMiddleware[] = [];
74
+
75
+ constructor(type: Constructable<T>);
76
+ constructor(type: Constructable<T>, connection: IConnection);
77
+ constructor(connection: IConnection, options: ReadonlyRepositoryMappingOptions<T>);
78
+ constructor(built: BuiltRepository<T>);
79
+ constructor();
80
+ constructor(
81
+ typeOrConnectionOrBuilt?: Constructable<T> | IConnection | BuiltRepository<T>,
82
+ connectionOrOptions?: IConnection | ReadonlyRepositoryMappingOptions<T>,
83
+ ) {
84
+ storedEnrichments.set(this, []);
85
+ if (typeOrConnectionOrBuilt === undefined) {
86
+ this.type = untyped();
87
+ return;
88
+ }
89
+ const built = builtOf(typeOrConnectionOrBuilt, connectionOrOptions);
90
+ if (!built) {
91
+ this.type = typeOrConnectionOrBuilt as Constructable<T>;
92
+ return;
93
+ }
94
+ this.type = built.type;
95
+ this.connection = built.connection;
96
+ this.rowConverter = built.rowConverter;
97
+ this.objectConverter = built.objectConverter;
98
+ this.entityMappers = built.entityMapper;
99
+ this.propertyMappers = built.propertyMappings;
100
+ this.statementMappers = new StatementMappers(built.entityMapper, built.propertyMappings);
101
+ this.readonlyStatements = built.statements;
102
+ }
103
+
104
+ addMiddleware = (middleware: ICommandMiddleware): this => {
105
+ this.middlewares.push(middleware);
106
+ return this;
107
+ };
108
+
109
+ addEnriched<TRelated extends object>(
110
+ enrichment: Enrichment,
111
+ via: IReadonlyRepository<TRelated>,
112
+ strategy?: IReadonlyEnrichmentStrategy<T & object>,
113
+ ): this {
114
+ const chosen = strategy ?? new DefaultReadonlyEnrichmentStrategy<T & object>();
115
+ this.entries().push(
116
+ new StoredEnrichment<T & object>(
117
+ enrichment,
118
+ (parents, sources) => chosen.apply(via, enrichment, parents, sources),
119
+ ),
120
+ );
121
+ return this;
122
+ }
123
+
124
+ async *read(
125
+ query?: ReadQuery,
126
+ parameters?: Parameter[],
127
+ options?: ReadonlyRepositoryMappingOptions<T>,
128
+ ): AsyncIterable<T> {
129
+ for await (const sourced of this.readTracked(query, parameters, options)) yield sourced.item;
130
+ }
131
+
132
+ async readSingle(
133
+ query?: ReadQuery,
134
+ parameters?: Parameter[],
135
+ options?: ReadonlyRepositoryMappingOptions<T>,
136
+ ): Promise<T | undefined> {
137
+ for await (const item of this.read(query, parameters, options)) return item;
138
+ return undefined;
139
+ }
140
+
141
+ protected get enriched(): boolean {
142
+ return this.entries().length > 0;
143
+ }
144
+
145
+ protected command = (): ICommand =>
146
+ this.middlewares.reduce(
147
+ (command, middleware) => command.addMiddleware(middleware),
148
+ this.connection!.createCommand(),
149
+ );
150
+
151
+ protected column = (property: string): string => this.statementMappers.column(property);
152
+
153
+ protected cell = (
154
+ property: string,
155
+ value: Cell,
156
+ fieldsApplied: boolean,
157
+ options?: ReadonlyRepositoryMappingOptions<T>,
158
+ ): Cell => {
159
+ const objects = options?.objectConverter ?? this.objectConverter;
160
+ const field =
161
+ objects instanceof MetaDataRowTypeConverter ? objects.fields[property] : undefined;
162
+ return field && !fieldsApplied ? field.reverseConvert(value) : value;
163
+ };
164
+
165
+ private entries = (): StoredEnrichment<T & object>[] =>
166
+ storedEnrichments.get(this) as StoredEnrichment<T & object>[];
167
+
168
+ private mappers = (options?: ReadonlyRepositoryMappingOptions<T>): StatementMappers =>
169
+ options?.entityMapper === undefined && options?.propertyMappings === undefined
170
+ ? this.statementMappers
171
+ : new StatementMappers(
172
+ options?.entityMapper ?? this.entityMappers,
173
+ options?.propertyMappings ?? this.propertyMappers,
174
+ );
175
+
176
+ private rowConverterOf = (options?: ReadonlyRepositoryMappingOptions<T>): TypeConverter<Cells, Cells> | undefined =>
177
+ options?.rowConverter ?? this.rowConverter;
178
+
179
+ private objects = (options?: ReadonlyRepositoryMappingOptions<T>): TypeConverter<T, Cells> =>
180
+ options?.objectConverter ??
181
+ this.objectConverter ??
182
+ (() => {
183
+ throw new DatasourceError("Object converter required");
184
+ })();
185
+
186
+ private async *readTracked(
187
+ query?: ReadQuery,
188
+ parameters?: Parameter[],
189
+ options?: ReadonlyRepositoryMappingOptions<T>,
190
+ ): AsyncIterable<Sourced<T>> {
191
+ const mappers = this.mappers(options);
192
+ const statement = mappers.apply(
193
+ query instanceof ExecuteStoredProcedureStatement ? query : this.readQuery(query, mappers, options),
194
+ (name, value) => this.cell(name, value, false, options),
195
+ );
196
+ const listed =
197
+ parameters ??
198
+ (statement instanceof SelectStatement ? statement.where?.parameters : undefined);
199
+ yield* this.apply(this.readItems(statement, listed, mappers, this.rowConverterOf(options), this.objects(options)));
200
+ }
201
+
202
+ private async *apply(pairs: AsyncIterable<Sourced<T>>): AsyncIterable<Sourced<T>> {
203
+ if (!this.enriched) {
204
+ yield* pairs;
205
+ return;
206
+ }
207
+ yield* this.sourced(pairs);
208
+ }
209
+
210
+ private convertObject = (row: Cells, objects: TypeConverter<T, Cells>): T =>
211
+ objects instanceof MetaDataRowTypeConverter
212
+ ? objects.convert(row, this.type)
213
+ : objects.convert(row);
214
+
215
+ private async *readItems(
216
+ query: IStatement | undefined,
217
+ parameters: Parameter[] | undefined,
218
+ mappers: StatementMappers,
219
+ rows: TypeConverter<Cells, Cells> | undefined,
220
+ objects: TypeConverter<T, Cells>,
221
+ ): AsyncIterable<Sourced<T>> {
222
+ const statement = query ?? this.readonlyStatements!.select();
223
+ const reader = await executeReader(this.command(), statement, parameters);
224
+ try {
225
+ while (await reader.next()) {
226
+ const renamed = this.columnToPropertyName(
227
+ reader.current ??
228
+ (() => {
229
+ throw new DatasourceError("Reader current must be a row");
230
+ })(),
231
+ mappers,
232
+ );
233
+ yield {
234
+ item: this.convertObject(rows ? rows.convert(renamed) : renamed, objects),
235
+ source: renamed,
236
+ };
237
+ }
238
+ } finally {
239
+ await reader.dispose();
240
+ }
241
+ }
242
+
243
+ private async *sourced(pairs: AsyncIterable<Sourced<T>>): AsyncIterable<Sourced<T>> {
244
+ const items: T[] = [];
245
+ const sources: (Row | undefined)[] = [];
246
+ for await (const sourced of pairs) {
247
+ items.push(sourced.item);
248
+ sources.push(sourced.source);
249
+ }
250
+ await this.fill(items as (T & object)[], sources);
251
+ for (let index = 0; index < items.length; index++)
252
+ yield { item: items[index]!, source: sources[index] };
253
+ }
254
+
255
+ private fill = async (parents: (T & object)[], sources?: (Row | undefined)[]): Promise<void> => {
256
+ for (const entry of this.entries()) await entry.apply(parents, sources);
257
+ };
258
+
259
+ private columnToPropertyName = (row: Cells, mappers: StatementMappers): Cells =>
260
+ Object.fromEntries(Object.entries(row).map(([key, value]) => [mappers.property(key), value]));
261
+
262
+ private readQuery = (
263
+ query: ISelectStatement | IWhere | undefined,
264
+ mappers: StatementMappers,
265
+ options?: ReadonlyRepositoryMappingOptions<T>,
266
+ ): ISelectStatement | undefined =>
267
+ !query
268
+ ? this.readonlyStatements?.select()
269
+ : "where" in query
270
+ ? query
271
+ : this.readonlyStatements
272
+ ? this.readonlyStatements.select(
273
+ mappers.applyWhere(query, (name, cell) => this.cell(name, cell, false, options))!,
274
+ )
275
+ : new SelectStatement({ where: query });
276
+ }
@@ -0,0 +1,53 @@
1
+ import type { IConnection } from "./IConnection.ts";
2
+ import type { Constructable } from "./converters/Constructable.ts";
3
+ import { MetaDataRowTypeConverter } from "./converters/MetaDataRowTypeConverter.ts";
4
+ import { fieldNamesOf } from "./createReadonlyRepositoryMappingOptions.ts";
5
+ import type { BuiltRepository } from "./BuiltRepository.ts";
6
+ import type { IMapper } from "./mappers/IMapper.ts";
7
+ import type { ReadonlyRepositoryMappingOptions } from "./ReadonlyRepositoryMappingOptions.ts";
8
+ import { ReadonlyRepositoryStatements } from "./ReadonlyRepositoryStatements.ts";
9
+ import { IdentityMapper } from "./mappers/IdentityMapper.ts";
10
+
11
+ export class ReadonlyRepositoryBuilder<T = object> {
12
+ protected entityMapper: IMapper<string, string> = new IdentityMapper();
13
+ protected propertyMapper: IMapper<string, string> = new IdentityMapper();
14
+
15
+ parts = (connection: IConnection, options: ReadonlyRepositoryMappingOptions<T>): BuiltRepository<T> => {
16
+ const rowConverter = options.rowConverter;
17
+ const objectConverter = options.objectConverter ?? new MetaDataRowTypeConverter<T>();
18
+ const entityMapper = options.entityMapper ?? new IdentityMapper<string>();
19
+ const propertyMappings = options.propertyMappings ?? new IdentityMapper<string>();
20
+ this.entityMapper = entityMapper;
21
+ this.propertyMapper = propertyMappings;
22
+ const entity = entityMapper.map(options.entity ?? options.type?.name ?? "");
23
+ const names = options.readProperties ?? (options.type ? fieldNamesOf(options.type) : []);
24
+ if (objectConverter instanceof MetaDataRowTypeConverter && options.type) {
25
+ const instance = new options.type() as Record<string, string | number | boolean | bigint | null | object>;
26
+ objectConverter.references.clear();
27
+ objectConverter.referenceColumns = propertyMappings;
28
+ for (const name of names) {
29
+ const value = instance[name];
30
+ if (value !== null && typeof value === "object" && !Array.isArray(value))
31
+ objectConverter.references.add(name);
32
+ }
33
+ }
34
+ const columns = [...names]
35
+ .map((name) => propertyMappings.map(name))
36
+ .sort((left, right) => left.localeCompare(right));
37
+ return {
38
+ connection,
39
+ rowConverter,
40
+ objectConverter,
41
+ propertyMappings,
42
+ entityMapper,
43
+ statements: this.statements(entity, columns),
44
+ ids: this.ids(options),
45
+ type: options.type ?? (Object as never as Constructable<T>),
46
+ };
47
+ };
48
+
49
+ protected ids = (_options: ReadonlyRepositoryMappingOptions<T>): string[] => [];
50
+
51
+ protected statements = (table: string, columns: string[]): ReadonlyRepositoryStatements =>
52
+ new ReadonlyRepositoryStatements(table, columns);
53
+ }
@@ -0,0 +1,15 @@
1
+ import type { Cell, Cells } from "./converters/Cell.ts";
2
+ import type { Constructable } from "./converters/Constructable.ts";
3
+ import type { TypeConverter } from "./converters/TypeConverter.ts";
4
+ import type { IMapper } from "./mappers/IMapper.ts";
5
+
6
+ export type ReadonlyRepositoryMappingOptions<T = Cells> = {
7
+ entity?: string;
8
+ entityMapper?: IMapper<string, string>;
9
+ propertyMappings?: IMapper<string, string>;
10
+ rowConverter?: TypeConverter<Cells, Cells>;
11
+ objectConverter?: TypeConverter<T, Cells>;
12
+ type?: Constructable<T>;
13
+ rowTypeConverters?: Record<string, TypeConverter<Cell, Cell>>;
14
+ readProperties?: string[];
15
+ };
@@ -0,0 +1,13 @@
1
+ import type { ISelectStatement } from "./statements/ISelectStatement.ts";
2
+ import type { IWhere } from "./statements/IWhere.ts";
3
+ import { SelectStatement } from "./statements/SelectStatement.ts";
4
+
5
+ export class ReadonlyRepositoryStatements {
6
+ constructor(
7
+ protected readonly table: string,
8
+ readonly readColumns: readonly string[],
9
+ ) {}
10
+
11
+ select = (where?: IWhere): ISelectStatement =>
12
+ new SelectStatement({ table: this.table, fields: [...this.readColumns], where });
13
+ }
@@ -0,0 +1,14 @@
1
+ import type { IConnection } from "./IConnection.ts";
2
+ import type { ICRUDRepository } from "./ICRUDRepository.ts";
3
+ import type { IReadonlyRepository } from "./IReadonlyRepository.ts";
4
+
5
+ export class RepositoryAccess {
6
+ constructor(
7
+ private readonly createRepo: (connection: IConnection) => ICRUDRepository,
8
+ private readonly createReadonlyRepo: (connection: IConnection) => IReadonlyRepository,
9
+ private readonly connection: IConnection,
10
+ ) {}
11
+
12
+ create = (): ICRUDRepository => this.createRepo(this.connection);
13
+ createReadonly = (): IReadonlyRepository => this.createReadonlyRepo(this.connection);
14
+ }
@@ -0,0 +1,94 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import type { IReadonlyRepository } from "./IReadonlyRepository.ts";
3
+ import { MockConnection } from "./mocks/mock-connection.ts";
4
+ import { MockRepository } from "./mocks/mock-repository.ts";
5
+ import { RepositoryFactory } from "./RepositoryFactory.ts";
6
+ import { RepositoryNotRegisteredError } from "./RepositoryNotRegisteredError.ts";
7
+
8
+ class Item {}
9
+
10
+ const emptyReadonly = (): IReadonlyRepository<Item> => ({
11
+ type: Item,
12
+ readSingle: async () => undefined,
13
+ async *read() {},
14
+ });
15
+
16
+ describe("RepositoryFactory", () => {
17
+ it("registers and creates", () => {
18
+ const factory = new RepositoryFactory();
19
+ const repo = new MockRepository<Item>(new MockConnection(), Item);
20
+ factory.register(repo);
21
+ const created = factory.create(Item);
22
+
23
+ expect(created).toBe(repo);
24
+ expect(factory.asReadonly.create(Item)).toBe(repo);
25
+ });
26
+
27
+ it("readonly registration is not crud", () => {
28
+ const factory = new RepositoryFactory();
29
+ const repo = emptyReadonly();
30
+ factory.asReadonly.register(repo);
31
+
32
+ expect(factory.asReadonly.create(Item)).toBe(repo);
33
+ expect(() => factory.create(Item)).toThrow(RepositoryNotRegisteredError);
34
+ try {
35
+ factory.create(Item);
36
+ } catch (error) {
37
+ expect(error).toBeInstanceOf(RepositoryNotRegisteredError);
38
+ expect((error as RepositoryNotRegisteredError).entityTypeName).toBe("Item");
39
+ expect((error as Error).message).toContain("Item");
40
+ }
41
+ });
42
+
43
+ it("registers and creates by name", () => {
44
+ const factory = new RepositoryFactory();
45
+ const connection = new MockConnection();
46
+ const crud = new MockRepository<Item>(connection, Item);
47
+ const read = emptyReadonly();
48
+ factory.register("Contact", "contacts", () => crud, () => read);
49
+
50
+ expect(factory.create("Contact", connection)).toBe(crud);
51
+ expect(factory.createReadonly("contacts", connection)).toBe(read);
52
+ expect(factory.access("contacts", connection).create()).toBe(crud);
53
+ expect(factory.access("Contact", connection).createReadonly()).toBe(read);
54
+ });
55
+
56
+ it("binds register on construct", () => {
57
+ RepositoryFactory.resetBinders();
58
+ const connection = new MockConnection();
59
+ const crud = new MockRepository<Item>(connection, Item);
60
+ const read = emptyReadonly();
61
+ RepositoryFactory.bind((factory) =>
62
+ factory.register("Contact", "contacts", () => crud, () => read),
63
+ );
64
+ try {
65
+ const factory = new RepositoryFactory();
66
+ expect(factory.create("contacts", connection)).toBe(crud);
67
+ } finally {
68
+ RepositoryFactory.resetBinders();
69
+ }
70
+ });
71
+
72
+ it("binds register on access", () => {
73
+ RepositoryFactory.resetBinders();
74
+ const connection = new MockConnection();
75
+ const crud = new MockRepository<Item>(connection, Item);
76
+ const read = emptyReadonly();
77
+ RepositoryFactory.bind((factory) =>
78
+ factory.register("Contact", "contacts", () => crud, () => read),
79
+ );
80
+ try {
81
+ const factory = new RepositoryFactory();
82
+ expect(factory.access("contacts", connection).create()).toBe(crud);
83
+ } finally {
84
+ RepositoryFactory.resetBinders();
85
+ }
86
+ });
87
+
88
+ it("throws when missing", () => {
89
+ const factory = new RepositoryFactory();
90
+ expect(() => factory.create(Item)).toThrow(RepositoryNotRegisteredError);
91
+ expect(() => factory.create("Contacts", new MockConnection())).toThrow(RepositoryNotRegisteredError);
92
+ expect(() => factory.createReadonly("Contacts", new MockConnection())).toThrow(RepositoryNotRegisteredError);
93
+ });
94
+ });
@@ -0,0 +1,115 @@
1
+ import type { Constructable } from "./converters/Constructable.ts";
2
+ import type { IConnection } from "./IConnection.ts";
3
+ import type { IReadonlyRepository } from "./IReadonlyRepository.ts";
4
+ import type { IRepository } from "./IRepository.ts";
5
+ import type { IRepositoryFactory } from "./IRepositoryFactory.ts";
6
+ import type { ICRUDRepository } from "./ICRUDRepository.ts";
7
+ import type { ICRUDRepositoryFactory } from "./ICRUDRepositoryFactory.ts";
8
+ import { RepositoryAccess } from "./RepositoryAccess.ts";
9
+ import { RepositoryNotRegisteredError } from "./RepositoryNotRegisteredError.ts";
10
+
11
+ type Named = {
12
+ create: (connection: IConnection) => ICRUDRepository;
13
+ createReadonly: (connection: IConnection) => IReadonlyRepository;
14
+ };
15
+
16
+ const binders: Array<(factory: RepositoryFactory) => void> = [];
17
+
18
+ export class RepositoryFactory implements ICRUDRepositoryFactory {
19
+ readonly #readonlyByType = new Map<Constructable<unknown>, IRepository>();
20
+ readonly #crudByType = new Map<Constructable<unknown>, IRepository>();
21
+ readonly #byName = new Map<string, Named>();
22
+
23
+ constructor() {
24
+ this.applyBound();
25
+ }
26
+
27
+ static bind = (register: (factory: RepositoryFactory) => void): void => {
28
+ binders.push(register);
29
+ };
30
+
31
+ static resetBinders = (): void => {
32
+ binders.length = 0;
33
+ };
34
+
35
+ private applyBound(): void {
36
+ for (const register of binders) register(this);
37
+ }
38
+
39
+ register(repository: IRepository): void;
40
+ register(
41
+ typeName: string,
42
+ pluralName: string,
43
+ create: (connection: IConnection) => ICRUDRepository,
44
+ createReadonly: (connection: IConnection) => IReadonlyRepository,
45
+ ): void;
46
+ register(
47
+ repositoryOrType: IRepository | string,
48
+ pluralName?: string,
49
+ create?: (connection: IConnection) => ICRUDRepository,
50
+ createReadonly?: (connection: IConnection) => IReadonlyRepository,
51
+ ): void {
52
+ if (typeof repositoryOrType !== "string") {
53
+ this.#put(repositoryOrType, true);
54
+ return;
55
+ }
56
+ const named = { create: create as Named["create"], createReadonly: createReadonly as Named["createReadonly"] };
57
+ this.#byName.set(repositoryOrType, named);
58
+ this.#byName.set(pluralName as string, named);
59
+ }
60
+
61
+ create<T>(type: Constructable<T>): ICRUDRepository<T>;
62
+ create(name: string, connection: IConnection): ICRUDRepository;
63
+ create(
64
+ typeOrName: Constructable<unknown> | string,
65
+ connection?: IConnection,
66
+ ): ICRUDRepository {
67
+ if (typeof typeOrName !== "string")
68
+ return this.#get(this.#crudByType, typeOrName) as ICRUDRepository;
69
+ this.applyBound();
70
+ return this.#lookup(typeOrName).create(connection as IConnection);
71
+ }
72
+
73
+ createReadonly = (name: string, connection: IConnection): IReadonlyRepository => {
74
+ this.applyBound();
75
+ return this.#lookup(name).createReadonly(connection);
76
+ };
77
+
78
+ access = (name: string, connection: IConnection): RepositoryAccess => {
79
+ this.applyBound();
80
+ const named = this.#lookup(name);
81
+ return new RepositoryAccess(named.create, named.createReadonly, connection);
82
+ };
83
+
84
+ has = (name: string): boolean => {
85
+ this.applyBound();
86
+ return this.#byName.has(name);
87
+ };
88
+
89
+ readonly asReadonly: IRepositoryFactory = {
90
+ register: (repository) => this.#put(repository, false),
91
+ create: <T>(type: Constructable<T>) =>
92
+ this.#get(this.#readonlyByType, type) as IReadonlyRepository<T>,
93
+ };
94
+
95
+ #put = (repository: IRepository, crud: boolean): void => {
96
+ this.#readonlyByType.set(repository.type, repository);
97
+ if (!crud) return;
98
+ this.#crudByType.set(repository.type, repository);
99
+ };
100
+
101
+ #get = (
102
+ map: Map<Constructable<unknown>, IRepository>,
103
+ type: Constructable<unknown>,
104
+ ): IRepository => {
105
+ const repository = map.get(type);
106
+ if (!repository) throw new RepositoryNotRegisteredError(type.name);
107
+ return repository;
108
+ };
109
+
110
+ #lookup = (name: string): Named => {
111
+ const named = this.#byName.get(name);
112
+ if (!named) throw new RepositoryNotRegisteredError(name);
113
+ return named;
114
+ };
115
+ }
@@ -0,0 +1,9 @@
1
+ export class RepositoryNotRegisteredError extends Error {
2
+ readonly entityTypeName: string;
3
+
4
+ constructor(entityTypeName: string) {
5
+ super(`Repository "${entityTypeName}" is not registered`);
6
+ this.name = "RepositoryNotRegisteredError";
7
+ this.entityTypeName = entityTypeName;
8
+ }
9
+ }
@@ -0,0 +1,6 @@
1
+ import type { IRepositoryTree } from "./IRepositoryTree.ts";
2
+ import type { IRepositoryTreeNode } from "./IRepositoryTreeNode.ts";
3
+
4
+ export class RepositoryTree implements IRepositoryTree {
5
+ constructor(readonly parent: IRepositoryTreeNode) {}
6
+ }
@@ -0,0 +1,11 @@
1
+ import type { Enrichment } from "./Enrichment.ts";
2
+ import type { IRepositoryTreeNode } from "./IRepositoryTreeNode.ts";
3
+
4
+ export class RepositoryTreeNode implements IRepositoryTreeNode {
5
+ constructor(
6
+ readonly value: object,
7
+ readonly propertyName: string,
8
+ readonly parent?: IRepositoryTreeNode,
9
+ readonly enrichment?: Enrichment,
10
+ ) {}
11
+ }
@@ -0,0 +1,15 @@
1
+ import { ParameterDirection } from "./ParameterDirection.ts";
2
+ import type { Parameter } from "./Parameter.ts";
3
+
4
+ export class Response {
5
+ readonly result: unknown;
6
+ readonly rowsAffected: number;
7
+ readonly parameters?: Parameter[];
8
+
9
+ constructor(result: unknown, rowsAffected: number, parameters?: Parameter[]) {
10
+ const returned = parameters?.find((parameter) => parameter.direction === ParameterDirection.ReturnValue)?.value;
11
+ this.result = result == null && returned != null ? returned : result;
12
+ this.rowsAffected = rowsAffected;
13
+ if (parameters !== undefined) this.parameters = parameters;
14
+ }
15
+ }
package/src/Row.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { Cell } from "./converters/Cell.ts";
2
+
3
+ export type Row = Record<string, Cell>;
@@ -0,0 +1,35 @@
1
+ import type { CRUDRepository } from "./CRUDRepository.ts";
2
+ import type { Response } from "./Response.ts";
3
+ import type { IWhere } from "./statements/IWhere.ts";
4
+ import type { IBulkWriteStrategy } from "./IBulkWriteStrategy.ts";
5
+
6
+ const fold = async <T>(
7
+ items: T[],
8
+ write: (item: T) => Promise<Response>,
9
+ ): Promise<Response> => {
10
+ let result: Response["result"] = null;
11
+ let rowsAffected = 0;
12
+ for (const item of items) {
13
+ const response = await write(item);
14
+ result = response.result;
15
+ rowsAffected += response.rowsAffected;
16
+ }
17
+ return { result, rowsAffected };
18
+ };
19
+
20
+ export class SingleCommandIBulkWriteStrategy<T extends object> implements IBulkWriteStrategy<T> {
21
+ repo!: CRUDRepository<T>;
22
+
23
+ attach = (): void => {};
24
+
25
+ create = async (items: T[]): Promise<Response> => {
26
+ for (const item of items) await this.repo.create(item);
27
+ return { result: null, rowsAffected: items.length };
28
+ };
29
+
30
+ update = (items: T[], byWhere: IWhere | undefined): Promise<Response> =>
31
+ fold(items, (item) => this.repo.update(item, byWhere));
32
+
33
+ delete = (items: T[], byWhere: IWhere | undefined): Promise<Response> =>
34
+ fold(items, (item) => this.repo.delete(item, byWhere));
35
+ }