@rvoh/dream 2.3.0-alpha.6 → 2.3.0-alpha.8

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/cjs/src/Dream.js +2 -40
  2. package/dist/cjs/src/cli/index.js +4 -0
  3. package/dist/cjs/src/dream/Query.js +14 -11
  4. package/dist/cjs/src/dream/QueryDriver/Base.js +0 -14
  5. package/dist/cjs/src/dream/QueryDriver/Kysely.js +86 -74
  6. package/dist/cjs/src/dream/QueryDriver/Postgres.js +10 -2
  7. package/dist/cjs/src/dream/internal/extractAssignableAssociationAttributes.js +9 -0
  8. package/dist/cjs/src/errors/db/DataIncompatibleWithDatabaseField.js +1 -3
  9. package/dist/cjs/src/helpers/areEqual.js +5 -0
  10. package/dist/cjs/src/helpers/cli/ASTBuilder.js +54 -2
  11. package/dist/cjs/src/helpers/cli/ASTKyselyCodegenEnhancer.js +84 -0
  12. package/dist/cjs/src/helpers/cli/ASTSchemaBuilder.js +17 -1
  13. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +16 -0
  14. package/dist/cjs/src/helpers/cloneDeepSafe.js +21 -10
  15. package/dist/cjs/src/helpers/customPgParsers.js +18 -1
  16. package/dist/cjs/src/helpers/db/normalizeDataForDb.js +81 -0
  17. package/dist/cjs/src/helpers/db/types/helpers.js +5 -0
  18. package/dist/cjs/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
  19. package/dist/cjs/src/helpers/sortBy.js +7 -5
  20. package/dist/cjs/src/helpers/sqlAttributes.js +4 -53
  21. package/dist/cjs/src/helpers/stringCasing.js +6 -5
  22. package/dist/cjs/src/helpers/toSafeObject.js +17 -0
  23. package/dist/cjs/src/package-exports/errors.js +2 -0
  24. package/dist/cjs/src/package-exports/index.js +2 -0
  25. package/dist/cjs/src/serializer/SerializerRenderer.js +11 -11
  26. package/dist/cjs/src/types/clocktime.js +1 -0
  27. package/dist/cjs/src/utils/datetime/BaseClockTime.js +363 -0
  28. package/dist/cjs/src/utils/datetime/CalendarDate.js +110 -119
  29. package/dist/cjs/src/utils/datetime/ClockTime.js +173 -0
  30. package/dist/cjs/src/utils/datetime/ClockTimeTz.js +232 -0
  31. package/dist/cjs/src/utils/datetime/DateTime.js +288 -193
  32. package/dist/cjs/src/utils/datetime/helpers/isoTimeDecimalString.js +1 -1
  33. package/dist/esm/src/Dream.js +2 -40
  34. package/dist/esm/src/cli/index.js +4 -0
  35. package/dist/esm/src/dream/Query.js +14 -11
  36. package/dist/esm/src/dream/QueryDriver/Base.js +0 -14
  37. package/dist/esm/src/dream/QueryDriver/Kysely.js +86 -74
  38. package/dist/esm/src/dream/QueryDriver/Postgres.js +10 -2
  39. package/dist/esm/src/dream/internal/extractAssignableAssociationAttributes.js +9 -0
  40. package/dist/esm/src/errors/db/DataIncompatibleWithDatabaseField.js +1 -3
  41. package/dist/esm/src/helpers/areEqual.js +5 -0
  42. package/dist/esm/src/helpers/cli/ASTBuilder.js +54 -2
  43. package/dist/esm/src/helpers/cli/ASTKyselyCodegenEnhancer.js +84 -0
  44. package/dist/esm/src/helpers/cli/ASTSchemaBuilder.js +17 -1
  45. package/dist/esm/src/helpers/cli/generateFactoryContent.js +16 -0
  46. package/dist/esm/src/helpers/cloneDeepSafe.js +21 -10
  47. package/dist/esm/src/helpers/customPgParsers.js +18 -1
  48. package/dist/esm/src/helpers/db/normalizeDataForDb.js +81 -0
  49. package/dist/esm/src/helpers/db/types/helpers.js +5 -0
  50. package/dist/esm/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
  51. package/dist/esm/src/helpers/sortBy.js +7 -5
  52. package/dist/esm/src/helpers/sqlAttributes.js +4 -53
  53. package/dist/esm/src/helpers/stringCasing.js +6 -5
  54. package/dist/esm/src/helpers/toSafeObject.js +17 -0
  55. package/dist/esm/src/package-exports/errors.js +2 -0
  56. package/dist/esm/src/package-exports/index.js +2 -0
  57. package/dist/esm/src/serializer/SerializerRenderer.js +11 -11
  58. package/dist/esm/src/types/clocktime.js +1 -0
  59. package/dist/esm/src/utils/datetime/BaseClockTime.js +363 -0
  60. package/dist/esm/src/utils/datetime/CalendarDate.js +110 -119
  61. package/dist/esm/src/utils/datetime/ClockTime.js +173 -0
  62. package/dist/esm/src/utils/datetime/ClockTimeTz.js +232 -0
  63. package/dist/esm/src/utils/datetime/DateTime.js +288 -193
  64. package/dist/esm/src/utils/datetime/helpers/isoTimeDecimalString.js +1 -1
  65. package/dist/types/src/Dream.d.ts +29 -33
  66. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -10
  67. package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +16 -16
  68. package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +1 -1
  69. package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
  70. package/dist/types/src/dream/Query.d.ts +16 -16
  71. package/dist/types/src/dream/QueryDriver/Base.d.ts +0 -1
  72. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +1 -0
  73. package/dist/types/src/dream/internal/associations/associationQuery.d.ts +1 -1
  74. package/dist/types/src/dream/internal/associations/associationUpdateQuery.d.ts +1 -1
  75. package/dist/types/src/dream/internal/associations/destroyAssociation.d.ts +1 -1
  76. package/dist/types/src/dream/internal/associations/throughAssociationHasOptionsBesidesThroughAndSource.d.ts +4 -2
  77. package/dist/types/src/dream/internal/associations/undestroyAssociation.d.ts +1 -1
  78. package/dist/types/src/dream/internal/extractAssignableAssociationAttributes.d.ts +3 -0
  79. package/dist/types/src/dream/internal/similarity/SimilarityBuilder.d.ts +7 -7
  80. package/dist/types/src/errors/db/DataIncompatibleWithDatabaseField.d.ts +2 -7
  81. package/dist/types/src/helpers/cli/ASTBuilder.d.ts +31 -0
  82. package/dist/types/src/helpers/cli/ASTKyselyCodegenEnhancer.d.ts +13 -0
  83. package/dist/types/src/helpers/customPgParsers.d.ts +5 -0
  84. package/dist/types/src/helpers/db/normalizeDataForDb.d.ts +6 -0
  85. package/dist/types/src/helpers/db/types/helpers.d.ts +5 -0
  86. package/dist/types/src/helpers/sort.d.ts +2 -1
  87. package/dist/types/src/helpers/sortBy.d.ts +3 -0
  88. package/dist/types/src/helpers/toSafeObject.d.ts +8 -0
  89. package/dist/types/src/package-exports/errors.d.ts +2 -0
  90. package/dist/types/src/package-exports/index.d.ts +2 -0
  91. package/dist/types/src/package-exports/types.d.ts +2 -1
  92. package/dist/types/src/types/associations/shared.d.ts +15 -13
  93. package/dist/types/src/types/associations/shared.ts +81 -41
  94. package/dist/types/src/types/calendardate.d.ts +22 -1
  95. package/dist/types/src/types/calendardate.ts +33 -1
  96. package/dist/types/src/types/clocktime.d.ts +22 -0
  97. package/dist/types/src/types/clocktime.ts +59 -0
  98. package/dist/types/src/types/datetime.d.ts +11 -18
  99. package/dist/types/src/types/datetime.ts +16 -21
  100. package/dist/types/src/types/dream.d.ts +27 -13
  101. package/dist/types/src/types/dream.ts +40 -14
  102. package/dist/types/src/types/variadic.d.ts +10 -9
  103. package/dist/types/src/types/variadic.ts +30 -5
  104. package/dist/types/src/utils/datetime/BaseClockTime.d.ts +287 -0
  105. package/dist/types/src/utils/datetime/CalendarDate.d.ts +65 -47
  106. package/dist/types/src/utils/datetime/ClockTime.d.ts +138 -0
  107. package/dist/types/src/utils/datetime/ClockTimeTz.d.ts +194 -0
  108. package/dist/types/src/utils/datetime/DateTime.d.ts +142 -56
  109. package/dist/types/src/utils/datetime/helpers/isoTimeDecimalString.d.ts +1 -1
  110. package/docs/assets/navigation.js +1 -1
  111. package/docs/assets/search.js +1 -1
  112. package/docs/classes/db.DreamMigrationHelpers.html +9 -9
  113. package/docs/classes/db.KyselyQueryDriver.html +33 -34
  114. package/docs/classes/db.PostgresQueryDriver.html +34 -35
  115. package/docs/classes/db.QueryDriverBase.html +32 -33
  116. package/docs/classes/errors.CheckConstraintViolation.html +4 -6
  117. package/docs/classes/errors.ColumnOverflow.html +4 -6
  118. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  119. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +4 -6
  120. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +4 -6
  121. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  122. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  123. package/docs/classes/errors.InvalidClockTime.html +17 -0
  124. package/docs/classes/errors.InvalidClockTimeTz.html +17 -0
  125. package/docs/classes/errors.InvalidDateTime.html +2 -2
  126. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  127. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  128. package/docs/classes/errors.NotNullViolation.html +4 -6
  129. package/docs/classes/errors.RecordNotFound.html +3 -3
  130. package/docs/classes/errors.ValidationError.html +3 -3
  131. package/docs/classes/index.CalendarDate.html +80 -92
  132. package/docs/classes/index.ClockTime.html +232 -0
  133. package/docs/classes/index.ClockTimeTz.html +253 -0
  134. package/docs/classes/index.DateTime.html +123 -129
  135. package/docs/classes/index.Decorators.html +19 -19
  136. package/docs/classes/index.Dream.html +127 -127
  137. package/docs/classes/index.DreamApp.html +5 -5
  138. package/docs/classes/index.DreamTransaction.html +2 -2
  139. package/docs/classes/index.Env.html +2 -2
  140. package/docs/classes/index.Query.html +71 -71
  141. package/docs/classes/system.CliFileWriter.html +2 -2
  142. package/docs/classes/system.DreamBin.html +2 -2
  143. package/docs/classes/system.DreamCLI.html +5 -5
  144. package/docs/classes/system.DreamImporter.html +2 -2
  145. package/docs/classes/system.DreamLogos.html +2 -2
  146. package/docs/classes/system.DreamSerializerBuilder.html +8 -8
  147. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  148. package/docs/classes/system.PathHelpers.html +3 -3
  149. package/docs/classes/utils.Encrypt.html +2 -2
  150. package/docs/classes/utils.Range.html +2 -2
  151. package/docs/functions/db.closeAllDbConnections.html +1 -1
  152. package/docs/functions/db.dreamDbConnections.html +1 -1
  153. package/docs/functions/db.untypedDb.html +1 -1
  154. package/docs/functions/db.validateColumn.html +1 -1
  155. package/docs/functions/db.validateTable.html +1 -1
  156. package/docs/functions/errors.pgErrorType.html +1 -1
  157. package/docs/functions/index.DreamSerializer.html +1 -1
  158. package/docs/functions/index.ObjectSerializer.html +1 -1
  159. package/docs/functions/index.ReplicaSafe.html +1 -1
  160. package/docs/functions/index.STI.html +1 -1
  161. package/docs/functions/index.SoftDelete.html +1 -1
  162. package/docs/functions/utils.camelize.html +1 -1
  163. package/docs/functions/utils.capitalize.html +1 -1
  164. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  165. package/docs/functions/utils.compact.html +1 -1
  166. package/docs/functions/utils.groupBy.html +1 -1
  167. package/docs/functions/utils.hyphenize.html +1 -1
  168. package/docs/functions/utils.intersection.html +1 -1
  169. package/docs/functions/utils.isEmpty.html +1 -1
  170. package/docs/functions/utils.normalizeUnicode.html +1 -1
  171. package/docs/functions/utils.pascalize.html +1 -1
  172. package/docs/functions/utils.percent.html +1 -1
  173. package/docs/functions/utils.range-1.html +1 -1
  174. package/docs/functions/utils.round.html +1 -1
  175. package/docs/functions/utils.sanitizeString.html +1 -1
  176. package/docs/functions/utils.snakeify.html +1 -1
  177. package/docs/functions/utils.sort.html +1 -1
  178. package/docs/functions/utils.sortBy.html +1 -1
  179. package/docs/functions/utils.sortObjectByKey.html +1 -1
  180. package/docs/functions/utils.sortObjectByValue.html +1 -1
  181. package/docs/functions/utils.uncapitalize.html +1 -1
  182. package/docs/functions/utils.uniq.html +1 -1
  183. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  184. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  185. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  186. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  187. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  188. package/docs/interfaces/types.DecoratorContext.html +2 -2
  189. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  190. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  191. package/docs/interfaces/types.DurationObject.html +5 -5
  192. package/docs/interfaces/types.EncryptOptions.html +2 -2
  193. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  194. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  195. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  196. package/docs/modules/db.html +1 -1
  197. package/docs/modules/errors.html +3 -1
  198. package/docs/modules/index.html +3 -1
  199. package/docs/modules/openapi.html +1 -1
  200. package/docs/modules/system.html +1 -1
  201. package/docs/modules/types.html +3 -1
  202. package/docs/modules/utils.html +1 -1
  203. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  204. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  205. package/docs/types/openapi.OpenapiFormats.html +1 -1
  206. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  207. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  208. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  209. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  210. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  211. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  212. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  213. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  214. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  215. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
  216. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
  217. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
  218. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +1 -1
  219. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  220. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  221. package/docs/types/openapi.OpenapiSchemaNull.html +1 -1
  222. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  223. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  224. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  225. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  226. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  227. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  228. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  229. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  230. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  231. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  232. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  233. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  234. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  235. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  236. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  237. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  238. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  239. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  240. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  241. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  242. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  243. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  244. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  245. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  246. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  247. package/docs/types/types.CalendarDateObject.html +2 -0
  248. package/docs/types/types.Camelized.html +1 -1
  249. package/docs/types/types.ClockTimeObject.html +2 -0
  250. package/docs/types/types.DbConnectionType.html +1 -1
  251. package/docs/types/types.DbTypes.html +1 -1
  252. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  253. package/docs/types/types.DreamAttributes.html +1 -1
  254. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  255. package/docs/types/types.DreamClassColumn.html +1 -1
  256. package/docs/types/types.DreamColumn.html +1 -1
  257. package/docs/types/types.DreamColumnNames.html +1 -1
  258. package/docs/types/types.DreamLogLevel.html +1 -1
  259. package/docs/types/types.DreamLogger.html +1 -1
  260. package/docs/types/types.DreamModelSerializerType.html +1 -1
  261. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  262. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  263. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  264. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  265. package/docs/types/types.DreamSerializable.html +1 -1
  266. package/docs/types/types.DreamSerializableArray.html +1 -1
  267. package/docs/types/types.DreamSerializerKey.html +1 -1
  268. package/docs/types/types.DreamSerializers.html +1 -1
  269. package/docs/types/types.DreamVirtualColumns.html +1 -1
  270. package/docs/types/types.DurationUnit.html +2 -4
  271. package/docs/types/types.EncryptAlgorithm.html +1 -1
  272. package/docs/types/types.HasManyStatement.html +1 -1
  273. package/docs/types/types.HasOneStatement.html +1 -1
  274. package/docs/types/types.Hyphenized.html +1 -1
  275. package/docs/types/types.Pascalized.html +1 -1
  276. package/docs/types/types.PrimaryKeyType.html +1 -1
  277. package/docs/types/types.RoundingPrecision.html +1 -1
  278. package/docs/types/types.SerializerCasing.html +1 -1
  279. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  280. package/docs/types/types.Snakeified.html +1 -1
  281. package/docs/types/types.StrictInterface.html +1 -1
  282. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  283. package/docs/types/types.UpdateableProperties.html +1 -1
  284. package/docs/types/types.ValidationType.html +1 -1
  285. package/docs/types/types.ViewModel.html +1 -1
  286. package/docs/types/types.ViewModelClass.html +1 -1
  287. package/docs/types/types.WeekdayName.html +1 -1
  288. package/docs/types/types.WhereStatementForDream.html +1 -1
  289. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  290. package/docs/variables/index.DreamConst.html +1 -1
  291. package/docs/variables/index.ops.html +1 -1
  292. package/docs/variables/openapi.openapiPrimitiveTypes-1.html +1 -1
  293. package/docs/variables/openapi.openapiShorthandPrimitiveTypes-1.html +1 -1
  294. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  295. package/docs/variables/system.primaryKeyTypes.html +1 -1
  296. package/package.json +2 -2
  297. package/dist/cjs/src/helpers/db/types/isDateOrDateArrayColumn.js +0 -3
  298. package/dist/cjs/src/helpers/db/types/isTextOrTextArrayColumn.js +0 -3
  299. package/dist/esm/src/helpers/db/types/isDateOrDateArrayColumn.js +0 -3
  300. package/dist/esm/src/helpers/db/types/isTextOrTextArrayColumn.js +0 -3
  301. package/dist/types/src/helpers/db/types/isDateOrDateArrayColumn.d.ts +0 -2
  302. package/dist/types/src/helpers/db/types/isTextOrTextArrayColumn.d.ts +0 -2
@@ -1,4 +1,5 @@
1
1
  import Dream from '../Dream.js';
2
+ import { ClockTime, ClockTimeTz } from '../package-exports/index.js';
2
3
  import CalendarDate from '../utils/datetime/CalendarDate.js';
3
4
  import { DateTime } from '../utils/datetime/DateTime.js';
4
5
  /**
@@ -34,6 +35,10 @@ function areEqualOrUndefined(a, b) {
34
35
  return b instanceof DateTime && a.equals(b);
35
36
  if (a instanceof CalendarDate)
36
37
  return b instanceof CalendarDate && a.equals(b);
38
+ if (a instanceof ClockTime)
39
+ return b instanceof ClockTime && a.equals(b);
40
+ if (a instanceof ClockTimeTz)
41
+ return b instanceof ClockTimeTz && a.equals(b);
37
42
  if (Array.isArray(a))
38
43
  return Array.isArray(b) && a.length === b.length && !a.find((value, index) => !areEqual(value, b[index]));
39
44
  if (a instanceof Dream)
@@ -229,10 +229,19 @@ export default class ASTBuilder {
229
229
  dateTimeNamedImports // namedBindings
230
230
  );
231
231
  const dateTimeImportDeclaration = ts.factory.createImportDeclaration(undefined, dateTimeImportClause, ts.factory.createStringLiteral('../../src/utils/datetime/DateTime.js'));
232
- return [calendarImportDeclaration, dateTimeImportDeclaration];
232
+ const clockTimeImport = ts.factory.createImportClause(true, f.createIdentifier('ClockTime'), undefined);
233
+ const clockTimeImportDeclaration = ts.factory.createImportDeclaration(undefined, clockTimeImport, ts.factory.createStringLiteral('../../src/utils/datetime/ClockTime.js'));
234
+ const clockTimeTzImport = ts.factory.createImportClause(true, f.createIdentifier('ClockTimeTz'), undefined);
235
+ const clockTimeTzImportDeclaration = ts.factory.createImportDeclaration(undefined, clockTimeTzImport, ts.factory.createStringLiteral('../../src/utils/datetime/ClockTimeTz.js'));
236
+ return [
237
+ calendarImportDeclaration,
238
+ dateTimeImportDeclaration,
239
+ clockTimeImportDeclaration,
240
+ clockTimeTzImportDeclaration,
241
+ ];
233
242
  }
234
243
  else {
235
- const namedImports = ts.factory.createNamedImports(['CalendarDate', 'DateTime'].map(importName => f.createImportSpecifier(true, undefined, ts.factory.createIdentifier(importName))));
244
+ const namedImports = ts.factory.createNamedImports(['CalendarDate', 'DateTime', 'ClockTime', 'ClockTimeTz'].map(importName => f.createImportSpecifier(true, undefined, ts.factory.createIdentifier(importName))));
236
245
  const importClause = ts.factory.createImportClause(false, // isTypeOnly: false for the clause itself if not all imports are type only
237
246
  undefined, // name: undefined for default import
238
247
  namedImports // namedBindings
@@ -274,4 +283,47 @@ export default class ASTBuilder {
274
283
  const serializers = dreamApp.serializers;
275
284
  return Object.keys(serializers);
276
285
  }
286
+ /**
287
+ * @internal
288
+ *
289
+ * checks if a database type is a date type (with optional array suffix)
290
+ */
291
+ isDateDbType(dbType) {
292
+ return /^date[[\]]*$/.test(dbType);
293
+ }
294
+ /**
295
+ * @internal
296
+ *
297
+ * checks if a database type is a time without time zone type (with optional array suffix)
298
+ */
299
+ isTimeWithoutTimeZoneDbType(dbType) {
300
+ return /^time without time zone[[\]]*$/.test(dbType);
301
+ }
302
+ /**
303
+ * @internal
304
+ *
305
+ * checks if a database type is a time with time zone type (with optional array suffix)
306
+ */
307
+ isTimeWithTimeZoneDbType(dbType) {
308
+ return /^time with time zone[[\]]*$/.test(dbType);
309
+ }
310
+ /**
311
+ * @internal
312
+ *
313
+ * checks if a database type is any time type (with or without time zone, with optional array suffix)
314
+ */
315
+ isTimeDbType(dbType) {
316
+ return /^time (without|with) time zone(\[\])?$/.test(dbType);
317
+ }
318
+ /**
319
+ * @internal
320
+ *
321
+ * checks if a TypeScript type node represents a string-like type
322
+ * (string keyword, string type reference, or string literal)
323
+ */
324
+ isStringLikeType(node, sourceFile) {
325
+ return (node.kind === ts.SyntaxKind.StringKeyword ||
326
+ (ts.isTypeReferenceNode(node) && node.typeName.getText(sourceFile) === 'string') ||
327
+ (ts.isLiteralTypeNode(node) && ts.isStringLiteral(node.literal)));
328
+ }
277
329
  }
@@ -1,6 +1,7 @@
1
1
  import ts from 'typescript';
2
2
  import { CliFileWriter } from '../../cli/CliFileWriter.js';
3
3
  import camelize from '../camelize.js';
4
+ import snakeify from '../snakeify.js';
4
5
  import ASTConnectionBuilder from './ASTConnectionBuilder.js';
5
6
  import autogeneratedFileDisclaimer from './autoGeneratedFileDisclaimer.js';
6
7
  const f = ts.factory;
@@ -25,6 +26,7 @@ export default class ASTKyselyCodegenEnhancer extends ASTConnectionBuilder {
25
26
  let dbSourceFile = await this.getDbSourceFile();
26
27
  dbSourceFile = this.camelizeKeys(dbSourceFile);
27
28
  dbSourceFile = this.replaceTimestampExport(dbSourceFile);
29
+ dbSourceFile = await this.replaceTimeFieldsInInterfaces(dbSourceFile);
28
30
  dbSourceFile = this.addMissingImports(dbSourceFile);
29
31
  dbSourceFile = this.replaceInt8Export(dbSourceFile);
30
32
  dbSourceFile = this.sortExportedInterfacesTransformer(dbSourceFile);
@@ -90,6 +92,88 @@ ${output}`);
90
92
  const result = ts.transform(dbSourceFile, [transformer]);
91
93
  return result.transformed[0];
92
94
  }
95
+ /**
96
+ * @internal
97
+ *
98
+ * Replaces string types with TimeWithZone or TimeWithoutZone for TIME columns
99
+ * based on the schema metadata from dream.ts
100
+ */
101
+ async replaceTimeFieldsInInterfaces(dbSourceFile) {
102
+ const schemaData = await this.getSchemaData();
103
+ const transformer = context => {
104
+ return sourceFile => {
105
+ const visitor = (node) => {
106
+ if (ts.isInterfaceDeclaration(node) && node.name.text !== 'DB') {
107
+ const tableName = snakeify(node.name.text);
108
+ const tableSchema = schemaData[tableName];
109
+ if (!tableSchema) {
110
+ return ts.visitEachChild(node, visitor, context);
111
+ }
112
+ const updatedMembers = node.members.map(member => {
113
+ if (ts.isPropertySignature(member) && ts.isIdentifier(member.name)) {
114
+ const columnName = member.name.text;
115
+ const columnSchema = tableSchema.columns[columnName];
116
+ if (!columnSchema)
117
+ return member;
118
+ const dbType = columnSchema.dbType;
119
+ // Check if this is a TIME field that's currently typed as string
120
+ if (this.isTimeDbType(dbType) && member.type) {
121
+ const isTimeTz = this.isTimeWithTimeZoneDbType(dbType);
122
+ const newType = this.replaceStringWithClockTimeType(member.type, sourceFile, isTimeTz);
123
+ if (newType !== member.type) {
124
+ return f.updatePropertySignature(member, member.modifiers, member.name, member.questionToken, newType);
125
+ }
126
+ }
127
+ }
128
+ return member;
129
+ });
130
+ return f.updateInterfaceDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, updatedMembers);
131
+ }
132
+ return ts.visitEachChild(node, visitor, context);
133
+ };
134
+ return ts.visitNode(sourceFile, visitor);
135
+ };
136
+ };
137
+ const result = ts.transform(dbSourceFile, [transformer]);
138
+ return result.transformed[0];
139
+ }
140
+ /**
141
+ * @internal
142
+ *
143
+ * Helper to replace string type references with ClockTime or ClockTimeTz type references
144
+ */
145
+ replaceStringWithClockTimeType(typeNode, sourceFile, isTimeTz) {
146
+ const toTimeType = () => f.createTypeReferenceNode(f.createIdentifier(isTimeTz ? 'ClockTimeTz' : 'ClockTime'));
147
+ // Handle union types (e.g., string | null)
148
+ if (ts.isUnionTypeNode(typeNode)) {
149
+ const updatedTypes = typeNode.types.map(t => this.replaceStringWithClockTimeType(t, sourceFile, isTimeTz));
150
+ return f.createUnionTypeNode(updatedTypes);
151
+ }
152
+ // Handle array syntax (e.g., string[])
153
+ if (ts.isArrayTypeNode(typeNode)) {
154
+ const elementType = this.isStringLikeType(typeNode.elementType, sourceFile)
155
+ ? toTimeType()
156
+ : this.replaceStringWithClockTimeType(typeNode.elementType, sourceFile, isTimeTz);
157
+ return f.createArrayTypeNode(elementType);
158
+ }
159
+ // Handle generic array syntax (e.g., Array<string>)
160
+ if (ts.isTypeReferenceNode(typeNode) &&
161
+ typeNode.typeName.getText(sourceFile) === 'Array' &&
162
+ typeNode.typeArguments?.length === 1) {
163
+ const arg = typeNode.typeArguments?.[0];
164
+ if (!arg)
165
+ return typeNode;
166
+ const nextArg = this.isStringLikeType(arg, sourceFile)
167
+ ? toTimeType()
168
+ : this.replaceStringWithClockTimeType(arg, sourceFile, isTimeTz);
169
+ return f.createTypeReferenceNode(f.createIdentifier('Array'), [nextArg]);
170
+ }
171
+ // Handle direct string type
172
+ if (this.isStringLikeType(typeNode, sourceFile)) {
173
+ return toTimeType();
174
+ }
175
+ return typeNode;
176
+ }
93
177
  /**
94
178
  * @internal
95
179
  *
@@ -262,7 +262,9 @@ ${output}`;
262
262
  */
263
263
  coercedType(dbSourceFile, propertySignature, dbType, importedModules) {
264
264
  const extractedPropertyTypes = this.extractTypeNodesFromTypeOrUnion(propertySignature);
265
- const isDate = /^date[[\]]*$/.test(dbType);
265
+ const isDate = this.isDateDbType(dbType);
266
+ const isTime = this.isTimeWithoutTimeZoneDbType(dbType);
267
+ const isTimeTz = this.isTimeWithTimeZoneDbType(dbType);
266
268
  const types = compact(extractedPropertyTypes.map(typeNode => {
267
269
  const typeText = typeNode.getText(dbSourceFile);
268
270
  let defaultReturnNode = /^Generated/.test(typeText) ? this.getFirstGenericType(typeNode) : typeNode;
@@ -287,6 +289,20 @@ ${output}`;
287
289
  return isDate
288
290
  ? f.createArrayTypeNode(f.createTypeReferenceNode('CalendarDate'))
289
291
  : f.createArrayTypeNode(f.createTypeReferenceNode('DateTime'));
292
+ case 'string':
293
+ // Kysely-codegen types TIME columns as string, we need to check dbType
294
+ if (isTime)
295
+ return f.createTypeReferenceNode('ClockTime');
296
+ if (isTimeTz)
297
+ return f.createTypeReferenceNode('ClockTimeTz');
298
+ return defaultReturnNode;
299
+ case 'string[]':
300
+ // Kysely-codegen types TIME[] columns as string[], we need to check dbType
301
+ if (isTime)
302
+ return f.createArrayTypeNode(f.createTypeReferenceNode('ClockTime'));
303
+ if (isTimeTz)
304
+ return f.createArrayTypeNode(f.createTypeReferenceNode('ClockTimeTz'));
305
+ return defaultReturnNode;
290
306
  case 'Int8':
291
307
  return f.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
292
308
  case 'Int8[]':
@@ -97,6 +97,22 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
97
97
  dreamImports.push('DateTime');
98
98
  attributeDefaults.push(`${attributeVariable}: [DateTime.now()],`);
99
99
  break;
100
+ case 'time':
101
+ dreamImports.push('ClockTime');
102
+ attributeDefaults.push(`${attributeVariable}: ClockTime.now(),`);
103
+ break;
104
+ case 'time[]':
105
+ dreamImports.push('ClockTime');
106
+ attributeDefaults.push(`${attributeVariable}: [ClockTime.now()],`);
107
+ break;
108
+ case 'timetz':
109
+ dreamImports.push('ClockTimeTz');
110
+ attributeDefaults.push(`${attributeVariable}: ClockTimeTz.now(),`);
111
+ break;
112
+ case 'timetz[]':
113
+ dreamImports.push('ClockTimeTz');
114
+ attributeDefaults.push(`${attributeVariable}: [ClockTimeTz.now()],`);
115
+ break;
100
116
  case 'uuid':
101
117
  nodeImports.push('randomUUID');
102
118
  attributeDefaults.push(`${attributeVariable}: randomUUID(),`);
@@ -1,5 +1,6 @@
1
1
  import Dream from '../Dream.js';
2
2
  import OpsStatement from '../ops/ops-statement.js';
3
+ import BaseClockTime from '../utils/datetime/BaseClockTime.js';
3
4
  import CalendarDate from '../utils/datetime/CalendarDate.js';
4
5
  import { DateTime } from '../utils/datetime/DateTime.js';
5
6
  import isObject from './isObject.js';
@@ -24,14 +25,13 @@ export default function cloneDeepSafe(original, unsupportedTypeCloneFunction) {
24
25
  return original;
25
26
  if (['number', 'boolean', 'bigint', 'symbol'].includes(typeof original))
26
27
  return original;
27
- if (original instanceof DateTime)
28
- return original;
29
- if (original instanceof CalendarDate)
30
- return original;
31
- if (original instanceof Range)
32
- return original;
33
- if (original instanceof OpsStatement)
28
+ if (original instanceof DateTime ||
29
+ original instanceof CalendarDate ||
30
+ original instanceof BaseClockTime ||
31
+ original instanceof Range ||
32
+ original instanceof OpsStatement) {
34
33
  return original;
34
+ }
35
35
  if (original instanceof Dream)
36
36
  return original['clone']();
37
37
  if (original?.isDreamQuery)
@@ -40,9 +40,20 @@ export default function cloneDeepSafe(original, unsupportedTypeCloneFunction) {
40
40
  return original;
41
41
  if (Array.isArray(original))
42
42
  return original.map(value => cloneDeepSafe(value, unsupportedTypeCloneFunction));
43
- if (isObject(original) && original.constructor.name === 'Object') {
44
- const clone = { ...original };
45
- Object.keys(clone).forEach(key => (clone[key] = cloneDeepSafe(clone[key], unsupportedTypeCloneFunction)));
43
+ // complex check here to ensure that if the object to clone was
44
+ // created using Object.create(null), we cannot access the constructor,
45
+ // and instead of to check that the original prototype is null
46
+ const isObjectLike = isObject(original) &&
47
+ (original.constructor?.name === 'Object' || Object.getPrototypeOf(original) === null);
48
+ if (isObjectLike) {
49
+ // if we are provided with an object that has a null prototype, create a new
50
+ // object with a null prototype to append to. Otherwise, create a standard
51
+ // object clone.
52
+ const clone = Object.getPrototypeOf(original) === null ? Object.create(null) : { ...original };
53
+ Object.keys(original).forEach(key => {
54
+ ;
55
+ clone[key] = cloneDeepSafe(original[key], unsupportedTypeCloneFunction);
56
+ });
46
57
  return clone;
47
58
  }
48
59
  if (unsupportedTypeCloneFunction)
@@ -1,4 +1,6 @@
1
1
  import CalendarDate from '../utils/datetime/CalendarDate.js';
2
+ import ClockTime from '../utils/datetime/ClockTime.js';
3
+ import ClockTimeTz from '../utils/datetime/ClockTimeTz.js';
2
4
  import { DateTime } from '../utils/datetime/DateTime.js';
3
5
  export async function findEnumArrayOids(kyselyDb) {
4
6
  const result = await kyselyDb.selectFrom('pg_type').select('typarray').where('typtype', '=', 'e').execute();
@@ -24,7 +26,22 @@ export function parsePostgresDate(dateString) {
24
26
  return dateString ? CalendarDate.fromSQL(dateString) : dateString;
25
27
  }
26
28
  export function parsePostgresDatetime(datetimeString) {
27
- return datetimeString ? DateTime.fromSQL(datetimeString, { zone: 'UTC' }) : datetimeString;
29
+ if (!datetimeString)
30
+ return datetimeString;
31
+ return DateTime.fromSQL(datetimeString, { zone: 'UTC' });
32
+ }
33
+ export function parsePostgresDatetimeTz(datetimeString) {
34
+ return parsePostgresDatetime(datetimeString);
35
+ }
36
+ export function parsePostgresTime(timeString) {
37
+ if (!timeString)
38
+ return timeString;
39
+ return ClockTime.fromSQL(timeString);
40
+ }
41
+ export function parsePostgresTimeTz(timeString) {
42
+ if (!timeString)
43
+ return timeString;
44
+ return ClockTimeTz.fromSQL(timeString, { zone: 'UTC' });
28
45
  }
29
46
  export function parsePostgresDecimal(numberString) {
30
47
  return numberString ? parseFloat(numberString) : numberString;
@@ -0,0 +1,81 @@
1
+ import DataTypeColumnTypeMismatch from '../../errors/db/DataTypeColumnTypeMismatch.js';
2
+ import BaseClockTime from '../../utils/datetime/BaseClockTime.js';
3
+ import CalendarDate from '../../utils/datetime/CalendarDate.js';
4
+ import ClockTime from '../../utils/datetime/ClockTime.js';
5
+ import ClockTimeTz from '../../utils/datetime/ClockTimeTz.js';
6
+ import { DateTime } from '../../utils/datetime/DateTime.js';
7
+ import normalizeUnicode from '../normalizeUnicode.js';
8
+ import { DATE_OR_DATE_ARRAY_COLUMN_CHECK_REGEXP, DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP, STRING_OR_STRING_ARRAY_COLUMN_CHECK_REGEXP, TIME_WITH_TIMEZONE_COLUMN_CHECK_REGEXP, TIME_WITHOUT_TIMEZONE_COLUMN_CHECK_REGEXP, } from './types/helpers.js';
9
+ export function normalizeDataForDb({ val, dreamClass, column, }) {
10
+ const columnType = dreamClass['cachedTypeFor'](column);
11
+ if (val instanceof DateTime || DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP.test(columnType)) {
12
+ return dateTimeOrDateToSql(DateTime, val);
13
+ //
14
+ }
15
+ else if (val instanceof CalendarDate || DATE_OR_DATE_ARRAY_COLUMN_CHECK_REGEXP.test(columnType)) {
16
+ return dateTimeOrDateToSql(CalendarDate, val);
17
+ //
18
+ }
19
+ else if (val instanceof ClockTime || TIME_WITHOUT_TIMEZONE_COLUMN_CHECK_REGEXP.test(columnType)) {
20
+ return clockTimeOrClockTimeTzToSql(ClockTime, val);
21
+ //
22
+ }
23
+ else if (val instanceof ClockTimeTz || TIME_WITH_TIMEZONE_COLUMN_CHECK_REGEXP.test(columnType)) {
24
+ return clockTimeOrClockTimeTzToSql(ClockTimeTz, val);
25
+ //
26
+ }
27
+ else if (typeof val === 'string' || STRING_OR_STRING_ARRAY_COLUMN_CHECK_REGEXP.test(columnType)) {
28
+ return normalizedString(val);
29
+ //
30
+ }
31
+ else {
32
+ return val;
33
+ }
34
+ }
35
+ function normalizedString(_val) {
36
+ const alreadyAnArray = Array.isArray(_val);
37
+ const normalizedValueArray = (alreadyAnArray ? _val : [_val]).map(val => typeof val === 'string' ? normalizeUnicode(val) : val);
38
+ return alreadyAnArray ? normalizedValueArray : normalizedValueArray[0];
39
+ }
40
+ function dateTimeOrDateToSql(dateClass, _val) {
41
+ const alreadyAnArray = Array.isArray(_val);
42
+ const normalizedValueArray = (alreadyAnArray ? _val : [_val]).map(val => {
43
+ if (val === null || val === undefined)
44
+ return val;
45
+ if (val instanceof DateTime || val instanceof CalendarDate)
46
+ return val.toSQL();
47
+ try {
48
+ if (typeof val !== 'string') {
49
+ throw new DataTypeColumnTypeMismatch(new Error(`database column type error: invalid ${dateClass.name} (received ${typeof val})`));
50
+ }
51
+ return dateClass.fromISO(val, { zone: 'UTC' }).toSQL();
52
+ }
53
+ catch (error) {
54
+ throw new DataTypeColumnTypeMismatch(error instanceof Error
55
+ ? error
56
+ : new Error(`database column type error: invalid ${dateClass.name} (received ${typeof val}: ${val})`));
57
+ }
58
+ });
59
+ return alreadyAnArray ? normalizedValueArray : normalizedValueArray[0];
60
+ }
61
+ function clockTimeOrClockTimeTzToSql(clockTimeClass, _val) {
62
+ const alreadyAnArray = Array.isArray(_val);
63
+ const normalizedValueArray = (alreadyAnArray ? _val : [_val]).map(val => {
64
+ if (val === null || val === undefined)
65
+ return val;
66
+ if (val instanceof BaseClockTime)
67
+ return val.toSQL();
68
+ try {
69
+ if (typeof val !== 'string') {
70
+ throw new DataTypeColumnTypeMismatch(new Error(`database column type error: invalid ${clockTimeClass.name} (received ${typeof val})`));
71
+ }
72
+ return clockTimeClass.fromISO(val, { zone: 'UTC' }).toSQL();
73
+ }
74
+ catch (error) {
75
+ throw new DataTypeColumnTypeMismatch(error instanceof Error
76
+ ? error
77
+ : new Error(`database column type error: invalid ${clockTimeClass.name} (received ${typeof val}: ${val})`));
78
+ }
79
+ });
80
+ return alreadyAnArray ? normalizedValueArray : normalizedValueArray[0];
81
+ }
@@ -0,0 +1,5 @@
1
+ export const DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP = /^timestamp/;
2
+ export const DATE_OR_DATE_ARRAY_COLUMN_CHECK_REGEXP = /^date/;
3
+ export const TIME_WITH_TIMEZONE_COLUMN_CHECK_REGEXP = /^time with time zone/;
4
+ export const TIME_WITHOUT_TIMEZONE_COLUMN_CHECK_REGEXP = /^time without time zone/;
5
+ export const STRING_OR_STRING_ARRAY_COLUMN_CHECK_REGEXP = /^(text|character varying|citext)/;
@@ -1,3 +1,4 @@
1
+ import { DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP } from './helpers.js';
1
2
  export default function isDatetimeOrDatetimeArrayColumn(dreamClass, column) {
2
- return /^timestamp/.test(dreamClass['cachedTypeFor'](column));
3
+ return DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP.test(dreamClass['cachedTypeFor'](column));
3
4
  }
@@ -1,3 +1,4 @@
1
+ import { ClockTime, ClockTimeTz } from '../package-exports/index.js';
1
2
  import CalendarDate from '../utils/datetime/CalendarDate.js';
2
3
  import { DateTime } from '../utils/datetime/DateTime.js';
3
4
  /**
@@ -26,11 +27,12 @@ export default function sortBy(array, valueToCompare) {
26
27
  return aPrime > bPrime ? 1 : aPrime < bPrime ? -1 : 0;
27
28
  if (typeof aPrime === 'string' && typeof bPrime === 'string')
28
29
  return aPrime.localeCompare(bPrime);
29
- if (aPrime instanceof DateTime && bPrime instanceof DateTime)
30
- return aPrime.valueOf() - bPrime.valueOf();
31
- if ((aPrime instanceof DateTime || aPrime instanceof CalendarDate) &&
32
- (bPrime instanceof DateTime || bPrime instanceof CalendarDate))
33
- return (aPrime.toISO() ?? '').localeCompare(bPrime.toISO() ?? '');
30
+ if (((aPrime instanceof DateTime || aPrime instanceof CalendarDate) &&
31
+ (bPrime instanceof DateTime || bPrime instanceof CalendarDate)) ||
32
+ (aPrime instanceof ClockTime && bPrime instanceof ClockTime) ||
33
+ (aPrime instanceof ClockTimeTz && bPrime instanceof ClockTimeTz)) {
34
+ return aPrime.valueOf().localeCompare(bPrime.valueOf());
35
+ }
34
36
  throw new UnsupportedValueFromComparisonFunction(aPrime, bPrime);
35
37
  });
36
38
  }
@@ -1,61 +1,12 @@
1
- import DreamApp from '../dream-app/index.js';
2
- import DataTypeColumnTypeMismatch from '../errors/db/DataTypeColumnTypeMismatch.js';
3
- import CalendarDate from '../utils/datetime/CalendarDate.js';
4
- import { DateTime } from '../utils/datetime/DateTime.js';
5
- import isDatetimeOrDatetimeArrayColumn from './db/types/isDatetimeOrDatetimeArrayColumn.js';
6
- import isTextOrTextArrayColumn from './db/types/isTextOrTextArrayColumn.js';
7
- import normalizeUnicode from './normalizeUnicode.js';
1
+ import { normalizeDataForDb } from './db/normalizeDataForDb.js';
8
2
  export default function sqlAttributes(dream) {
9
3
  const attributes = dream.dirtyAttributes();
10
4
  const dreamClass = dream.constructor;
11
- const queryDriverClass = DreamApp.getOrFail().dbConnectionQueryDriverClass(dream.connectionName);
12
- return Object.keys(attributes).reduce((result, key) => {
13
- let val = attributes[key];
5
+ return Object.keys(attributes).reduce((result, column) => {
6
+ const val = attributes[column];
14
7
  if (val === undefined)
15
8
  return result;
16
- if (Array.isArray(val)) {
17
- if (isDatetimeOrDatetimeArrayColumn(dreamClass, key))
18
- val = val.map(aVal => valueToDatetime(dream, aVal));
19
- else if (isTextOrTextArrayColumn(dreamClass, key))
20
- val = val.map(normalizeUnicode);
21
- }
22
- else {
23
- if (isDatetimeOrDatetimeArrayColumn(dreamClass, key))
24
- val = valueToDatetime(dream, val);
25
- else if (isTextOrTextArrayColumn(dreamClass, key))
26
- val = normalizeUnicode(val);
27
- }
28
- if (val instanceof DateTime || val instanceof CalendarDate) {
29
- const dateOrDatetime = val instanceof DateTime ? 'datetime' : 'date';
30
- // Converting toJSDate resulted in the correct timezone, but even with process.env.TZ=UTC,
31
- // Kysely inserted into the database with the machine timezone, which can shift the date
32
- // (e.g., toJSDate resulted in a JS Date that formats as "1987-04-07T00:00:00.000Z", but
33
- // Kysely inserted "1907-04-06" into the database). By converting to an SQL string before
34
- // handing off to Kysely, we bypass Javascript dates altogether, sending the string into the
35
- // database for storage as a date or datetime.
36
- result[key] = queryDriverClass.serializeDbType(dateOrDatetime, val);
37
- }
38
- else {
39
- result[key] = val;
40
- }
9
+ result[column] = normalizeDataForDb({ val, dreamClass, column });
41
10
  return result;
42
11
  }, {});
43
12
  }
44
- /**
45
- * Convert datetimes to UTC
46
- */
47
- function valueToDatetime(dream, val) {
48
- if (typeof val !== 'string')
49
- return val;
50
- let datetime;
51
- try {
52
- datetime = DateTime.fromISO(val, { zone: 'UTC' });
53
- }
54
- catch (error) {
55
- throw new DataTypeColumnTypeMismatch({
56
- dream,
57
- error: error instanceof Error ? error : new Error('database column type error'),
58
- });
59
- }
60
- return datetime.isValid ? datetime : val;
61
- }
@@ -1,4 +1,5 @@
1
1
  import Dream from '../Dream.js';
2
+ import BaseClockTime from '../utils/datetime/BaseClockTime.js';
2
3
  import CalendarDate from '../utils/datetime/CalendarDate.js';
3
4
  import { DateTime } from '../utils/datetime/DateTime.js';
4
5
  import isObject from './isObject.js';
@@ -17,12 +18,12 @@ function recursiveStringCase(target, stringCaser) {
17
18
  if (Array.isArray(target))
18
19
  return target.map(s => recursiveStringCase(s, stringCaser));
19
20
  if (isObject(target)) {
20
- if (target instanceof DateTime)
21
- return target;
22
- if (target instanceof CalendarDate)
23
- return target;
24
- if (target instanceof Dream)
21
+ if (target instanceof DateTime ||
22
+ target instanceof CalendarDate ||
23
+ target instanceof BaseClockTime ||
24
+ target instanceof Dream) {
25
25
  return target;
26
+ }
26
27
  return Object.keys(target).reduce((stringCasedObject, targetKey) => {
27
28
  stringCasedObject[stringCaser(targetKey)] = recursiveStringCase(target[targetKey], stringCaser);
28
29
  return stringCasedObject;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @internal
3
+ *
4
+ * Returns a shallow copy of the object using a prototype-less container
5
+ * (Object.create(null)). Use when assigning untrusted keys so that keys like
6
+ * __proto__ or constructor cannot pollute Object.prototype.
7
+ */
8
+ export function toSafeObject(obj) {
9
+ if (obj === null || typeof obj !== 'object')
10
+ return obj;
11
+ const safe = Object.create(null);
12
+ for (const key of Object.keys(obj)) {
13
+ ;
14
+ safe[key] = obj[key];
15
+ }
16
+ return safe;
17
+ }
@@ -11,4 +11,6 @@ export { default as RecordNotFound } from '../errors/RecordNotFound.js';
11
11
  export { default as MissingSerializersDefinition } from '../errors/serializers/MissingSerializersDefinition.js';
12
12
  export { default as ValidationError } from '../errors/ValidationError.js';
13
13
  export { InvalidCalendarDate } from '../utils/datetime/CalendarDate.js';
14
+ export { InvalidClockTime } from '../utils/datetime/ClockTime.js';
15
+ export { InvalidClockTimeTz } from '../utils/datetime/ClockTimeTz.js';
14
16
  export { InvalidDateTime } from '../utils/datetime/DateTime.js';
@@ -12,4 +12,6 @@ export { default as ops } from '../ops/index.js';
12
12
  export { default as DreamSerializer } from '../serializer/DreamSerializer.js';
13
13
  export { default as ObjectSerializer } from '../serializer/ObjectSerializer.js';
14
14
  export { default as CalendarDate } from '../utils/datetime/CalendarDate.js';
15
+ export { default as ClockTime } from '../utils/datetime/ClockTime.js';
16
+ export { default as ClockTimeTz } from '../utils/datetime/ClockTimeTz.js';
15
17
  export { DateTime } from '../utils/datetime/DateTime.js';
@@ -2,6 +2,7 @@ import RendersManyMustReceiveArray from '../errors/serializers/RendersManyMustRe
2
2
  import compact from '../helpers/compact.js';
3
3
  import round from '../helpers/round.js';
4
4
  import snakeify from '../helpers/snakeify.js';
5
+ import BaseClockTime from '../utils/datetime/BaseClockTime.js';
5
6
  import CalendarDate from '../utils/datetime/CalendarDate.js';
6
7
  import { DateTime } from '../utils/datetime/DateTime.js';
7
8
  import DreamSerializerBuilder from './builders/DreamSerializerBuilder.js';
@@ -42,7 +43,7 @@ export default class SerializerRenderer {
42
43
  const value = data[attribute.name] ?? attribute.options?.default;
43
44
  if (value === undefined && attribute.options?.required === false)
44
45
  return accumulator;
45
- accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(value, attribute.options, this.passthroughData, this.renderOpts);
46
+ accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(data, value, attribute.name, attribute.options, this.passthroughData, this.renderOpts);
46
47
  return accumulator;
47
48
  }
48
49
  /////////////////////
@@ -57,7 +58,7 @@ export default class SerializerRenderer {
57
58
  const value = target?.[attribute.name] ?? attribute.options?.default;
58
59
  if (value === undefined && attribute.options?.required === false)
59
60
  return accumulator;
60
- accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(value, attribute.options, this.passthroughData, this.renderOpts);
61
+ accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(target, value, attribute.name, attribute.options, this.passthroughData, this.renderOpts);
61
62
  return accumulator;
62
63
  }
63
64
  //////////////////////////////
@@ -77,11 +78,11 @@ export default class SerializerRenderer {
77
78
  if (attribute.options.flatten) {
78
79
  return {
79
80
  ...accumulator,
80
- ...applyRenderingOptionsToAttribute(value, {}, this.passthroughData, this.renderOpts),
81
+ ...applyRenderingOptionsToAttribute(null, value, attribute.name, {}, this.passthroughData, this.renderOpts),
81
82
  };
82
83
  }
83
84
  else {
84
- accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(value, {}, this.passthroughData, this.renderOpts);
85
+ accumulator[outputAttributeName] = applyRenderingOptionsToAttribute(null, value, attribute.name, {}, this.passthroughData, this.renderOpts);
85
86
  return accumulator;
86
87
  }
87
88
  }
@@ -187,18 +188,17 @@ export default class SerializerRenderer {
187
188
  }
188
189
  }
189
190
  }
190
- function applyRenderingOptionsToAttribute(value, options, passthroughData, renderOptions) {
191
+ function applyRenderingOptionsToAttribute(data, value, attributeName, options, passthroughData, renderOptions) {
191
192
  if (Array.isArray(value))
192
- return value.map(val => _applyRenderingOptionsToAttribute(val, options, passthroughData, renderOptions));
193
- return _applyRenderingOptionsToAttribute(value, options, passthroughData, renderOptions);
193
+ return value.map(val => _applyRenderingOptionsToAttribute(data, val, attributeName, options, passthroughData, renderOptions));
194
+ return _applyRenderingOptionsToAttribute(data, value, attributeName, options, passthroughData, renderOptions);
194
195
  }
195
- function _applyRenderingOptionsToAttribute(value, options, passthroughData, renderOptions) {
196
+ function _applyRenderingOptionsToAttribute(data, value, attributeName, options, passthroughData, renderOptions) {
196
197
  if (value instanceof DreamSerializerBuilder || value instanceof ObjectSerializerBuilder)
197
198
  return value.render(passthroughData, renderOptions);
198
- if (value instanceof DateTime)
199
- return value.toISO();
200
- if (value instanceof CalendarDate)
199
+ if (value instanceof DateTime || value instanceof CalendarDate || value instanceof BaseClockTime) {
201
200
  return value.toISO();
201
+ }
202
202
  if (typeof value === 'bigint')
203
203
  return value.toString();
204
204
  const precision = options?.precision;
@@ -0,0 +1 @@
1
+ export {};