@rvoh/dream 2.6.1-alpha.1 → 2.7.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 (204) hide show
  1. package/dist/cjs/src/bin/index.js +2 -0
  2. package/dist/cjs/src/cli/index.js +1 -0
  3. package/dist/cjs/src/helpers/cli/generateDream.js +7 -1
  4. package/dist/cjs/src/helpers/cli/generateDreamContent.js +44 -9
  5. package/dist/cjs/src/helpers/cli/generateMigration.js +2 -1
  6. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +28 -11
  7. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +53 -50
  8. package/dist/cjs/src/ops/index.js +245 -1
  9. package/dist/esm/src/bin/index.js +2 -0
  10. package/dist/esm/src/cli/index.js +1 -0
  11. package/dist/esm/src/helpers/cli/generateDream.js +7 -1
  12. package/dist/esm/src/helpers/cli/generateDreamContent.js +44 -9
  13. package/dist/esm/src/helpers/cli/generateMigration.js +2 -1
  14. package/dist/esm/src/helpers/cli/generateMigrationContent.js +28 -11
  15. package/dist/esm/src/helpers/cli/generateSerializerContent.js +53 -50
  16. package/dist/esm/src/ops/index.js +245 -1
  17. package/dist/types/src/bin/index.d.ts +1 -0
  18. package/dist/types/src/cli/index.d.ts +7 -0
  19. package/dist/types/src/helpers/cli/generateDream.d.ts +8 -0
  20. package/dist/types/src/helpers/cli/generateDreamContent.d.ts +11 -1
  21. package/dist/types/src/helpers/cli/generateMigration.d.ts +7 -1
  22. package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +7 -1
  23. package/dist/types/src/ops/index.d.ts +245 -0
  24. package/dist/types/src/types/associations/shared.d.ts +2 -2
  25. package/dist/types/src/types/associations/shared.ts +17 -11
  26. package/docs/assets/search.js +1 -1
  27. package/docs/classes/db.DreamMigrationHelpers.html +9 -9
  28. package/docs/classes/db.KyselyQueryDriver.html +32 -32
  29. package/docs/classes/db.PostgresQueryDriver.html +33 -33
  30. package/docs/classes/db.QueryDriverBase.html +31 -31
  31. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  32. package/docs/classes/errors.ColumnOverflow.html +3 -3
  33. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  34. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  35. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  36. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  37. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  38. package/docs/classes/errors.InvalidClockTime.html +2 -2
  39. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  40. package/docs/classes/errors.InvalidDateTime.html +2 -2
  41. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  42. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  43. package/docs/classes/errors.NotNullViolation.html +3 -3
  44. package/docs/classes/errors.RecordNotFound.html +3 -3
  45. package/docs/classes/errors.ValidationError.html +3 -3
  46. package/docs/classes/index.CalendarDate.html +33 -33
  47. package/docs/classes/index.ClockTime.html +32 -32
  48. package/docs/classes/index.ClockTimeTz.html +35 -35
  49. package/docs/classes/index.DateTime.html +86 -86
  50. package/docs/classes/index.Decorators.html +19 -19
  51. package/docs/classes/index.Dream.html +119 -119
  52. package/docs/classes/index.DreamApp.html +5 -5
  53. package/docs/classes/index.DreamTransaction.html +2 -2
  54. package/docs/classes/index.Env.html +2 -2
  55. package/docs/classes/index.Query.html +56 -56
  56. package/docs/classes/system.CliFileWriter.html +4 -4
  57. package/docs/classes/system.DreamBin.html +2 -2
  58. package/docs/classes/system.DreamCLI.html +6 -6
  59. package/docs/classes/system.DreamImporter.html +2 -2
  60. package/docs/classes/system.DreamLogos.html +2 -2
  61. package/docs/classes/system.DreamSerializerBuilder.html +11 -11
  62. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  63. package/docs/classes/system.PathHelpers.html +3 -3
  64. package/docs/classes/utils.Encrypt.html +2 -2
  65. package/docs/classes/utils.Range.html +2 -2
  66. package/docs/functions/db.closeAllDbConnections.html +1 -1
  67. package/docs/functions/db.dreamDbConnections.html +1 -1
  68. package/docs/functions/db.untypedDb.html +1 -1
  69. package/docs/functions/db.validateColumn.html +1 -1
  70. package/docs/functions/db.validateTable.html +1 -1
  71. package/docs/functions/errors.pgErrorType.html +1 -1
  72. package/docs/functions/index.DreamSerializer.html +1 -1
  73. package/docs/functions/index.ObjectSerializer.html +1 -1
  74. package/docs/functions/index.ReplicaSafe.html +1 -1
  75. package/docs/functions/index.STI.html +1 -1
  76. package/docs/functions/index.SoftDelete.html +1 -1
  77. package/docs/functions/utils.camelize.html +1 -1
  78. package/docs/functions/utils.capitalize.html +1 -1
  79. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  80. package/docs/functions/utils.compact.html +1 -1
  81. package/docs/functions/utils.groupBy.html +1 -1
  82. package/docs/functions/utils.hyphenize.html +1 -1
  83. package/docs/functions/utils.intersection.html +1 -1
  84. package/docs/functions/utils.isEmpty.html +1 -1
  85. package/docs/functions/utils.normalizeUnicode.html +1 -1
  86. package/docs/functions/utils.pascalize.html +1 -1
  87. package/docs/functions/utils.percent.html +1 -1
  88. package/docs/functions/utils.range.html +1 -1
  89. package/docs/functions/utils.round.html +1 -1
  90. package/docs/functions/utils.sanitizeString.html +1 -1
  91. package/docs/functions/utils.snakeify.html +1 -1
  92. package/docs/functions/utils.sort.html +1 -1
  93. package/docs/functions/utils.sortBy.html +1 -1
  94. package/docs/functions/utils.sortObjectByKey.html +1 -1
  95. package/docs/functions/utils.sortObjectByValue.html +1 -1
  96. package/docs/functions/utils.uncapitalize.html +1 -1
  97. package/docs/functions/utils.uniq.html +1 -1
  98. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  99. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  100. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  101. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  102. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  103. package/docs/interfaces/types.DecoratorContext.html +2 -2
  104. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  105. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  106. package/docs/interfaces/types.DurationObject.html +2 -2
  107. package/docs/interfaces/types.EncryptOptions.html +2 -2
  108. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  109. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  110. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  111. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  112. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  113. package/docs/types/openapi.OpenapiFormats.html +1 -1
  114. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  115. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  116. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  117. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  118. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  119. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  120. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  121. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  122. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  123. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +2 -2
  124. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +2 -2
  125. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +2 -2
  126. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  127. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  128. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  129. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  130. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  131. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  132. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  133. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  134. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  135. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  136. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  137. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  138. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  139. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  140. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  141. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  142. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +2 -2
  143. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +2 -2
  144. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +2 -2
  145. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  146. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  147. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  148. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  149. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  150. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  151. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  152. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  153. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  154. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  155. package/docs/types/types.CalendarDateObject.html +1 -1
  156. package/docs/types/types.Camelized.html +1 -1
  157. package/docs/types/types.ClockTimeObject.html +1 -1
  158. package/docs/types/types.DbConnectionType.html +1 -1
  159. package/docs/types/types.DbTypes.html +1 -1
  160. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  161. package/docs/types/types.DreamAttributes.html +1 -1
  162. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  163. package/docs/types/types.DreamClassColumn.html +1 -1
  164. package/docs/types/types.DreamColumn.html +1 -1
  165. package/docs/types/types.DreamColumnNames.html +1 -1
  166. package/docs/types/types.DreamLogLevel.html +1 -1
  167. package/docs/types/types.DreamLogger.html +2 -2
  168. package/docs/types/types.DreamModelSerializerType.html +1 -1
  169. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  170. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  171. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  172. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  173. package/docs/types/types.DreamSerializable.html +1 -1
  174. package/docs/types/types.DreamSerializableArray.html +1 -1
  175. package/docs/types/types.DreamSerializerKey.html +1 -1
  176. package/docs/types/types.DreamSerializers.html +1 -1
  177. package/docs/types/types.DreamVirtualColumns.html +1 -1
  178. package/docs/types/types.DurationUnit.html +1 -1
  179. package/docs/types/types.EncryptAlgorithm.html +1 -1
  180. package/docs/types/types.HasManyStatement.html +1 -1
  181. package/docs/types/types.HasOneStatement.html +1 -1
  182. package/docs/types/types.Hyphenized.html +1 -1
  183. package/docs/types/types.Pascalized.html +1 -1
  184. package/docs/types/types.PrimaryKeyType.html +1 -1
  185. package/docs/types/types.RoundingPrecision.html +1 -1
  186. package/docs/types/types.SerializerCasing.html +1 -1
  187. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  188. package/docs/types/types.Snakeified.html +1 -1
  189. package/docs/types/types.StrictInterface.html +1 -1
  190. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  191. package/docs/types/types.UpdateableProperties.html +1 -1
  192. package/docs/types/types.ValidationType.html +1 -1
  193. package/docs/types/types.ViewModel.html +2 -2
  194. package/docs/types/types.ViewModelClass.html +1 -1
  195. package/docs/types/types.WeekdayName.html +1 -1
  196. package/docs/types/types.WhereStatementForDream.html +1 -1
  197. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  198. package/docs/variables/index.DreamConst.html +1 -1
  199. package/docs/variables/index.ops.html +115 -1
  200. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  201. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  202. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  203. package/docs/variables/system.primaryKeyTypes.html +1 -1
  204. package/package.json +1 -1
@@ -1,4 +1,3 @@
1
- import serializerNameFromFullyQualifiedModelName from '../../serializer/helpers/serializerNameFromFullyQualifiedModelName.js';
2
1
  import camelize from '../camelize.js';
3
2
  import globalClassNameFromFullyQualifiedModelName from '../globalClassNameFromFullyQualifiedModelName.js';
4
3
  import absoluteDreamPath from '../path/absoluteDreamPath.js';
@@ -9,9 +8,18 @@ export default function generateSerializerContent({ fullyQualifiedModelName, col
9
8
  const additionalImports = [];
10
9
  const dreamImports = [];
11
10
  const isSTI = !!fullyQualifiedParentName;
11
+ // Variants that should be emitted in this file. Each variant generates a
12
+ // matching summary + default serializer pair; STI children import the
13
+ // corresponding variant from the parent module so the inheritance chain
14
+ // stays within the same variant (admin → admin, internal → internal).
15
+ const variantSuffixes = [''];
16
+ if (includeAdminSerializers)
17
+ variantSuffixes.push('Admin');
18
+ if (includeInternalSerializers)
19
+ variantSuffixes.push('Internal');
12
20
  if (isSTI) {
13
21
  fullyQualifiedParentName = standardizeFullyQualifiedModelName(fullyQualifiedParentName);
14
- additionalImports.push(importStatementForSerializer(fullyQualifiedModelName, fullyQualifiedParentName));
22
+ additionalImports.push(importStatementForSerializer(fullyQualifiedModelName, fullyQualifiedParentName, variantSuffixes));
15
23
  }
16
24
  else {
17
25
  dreamImports.push('DreamSerializer');
@@ -23,58 +31,50 @@ export default function generateSerializerContent({ fullyQualifiedModelName, col
23
31
  : `(${modelInstanceName}: ${modelClassName})`;
24
32
  const modelSerializerArgs = `${modelInstanceName}`;
25
33
  const dreamSerializerArgs = `${stiBaseSerializer ? `StiChildClass ?? ${modelClassName}` : modelClassName}, ${modelInstanceName}`;
26
- const serializerClassName = serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName));
27
- const summarySerializerClassName = serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName), 'summary');
28
- const defaultSerializerExtends = isSTI
29
- ? `${serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedParentName))}(${modelClassName}, ${modelSerializerArgs})`
30
- : `${summarySerializerClassName}(${stiBaseSerializer ? 'StiChildClass, ' : ''}${modelSerializerArgs})`;
31
- const summarySerializerExtends = isSTI
32
- ? `${serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedParentName), 'summary')}(${modelClassName}, ${modelSerializerArgs})`
33
- : `DreamSerializer(${dreamSerializerArgs})`;
34
- // Admin variants
35
- const adminSerializerClassName = serializerClassName.replace(/Serializer$/, 'AdminSerializer');
36
- const adminSummarySerializerClassName = summarySerializerClassName.replace(/SummarySerializer$/, 'AdminSummarySerializer');
37
- // end:Admin variants
38
- // Internal variants
39
- const internalSerializerClassName = serializerClassName.replace(/Serializer$/, 'InternalSerializer');
40
- const internalSummarySerializerClassName = summarySerializerClassName.replace(/SummarySerializer$/, 'InternalSummarySerializer');
41
- // end:Internal variants
34
+ const localSerializerBase = fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName);
35
+ const parentSerializerBase = isSTI
36
+ ? fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedParentName)
37
+ : '';
42
38
  const additionalModelImports = [];
43
39
  const dreamImport = dreamImports.length
44
40
  ? `import { ${uniq(dreamImports).join(', ')} } from '@rvoh/dream'\n`
45
41
  : '';
46
42
  const additionalImportsStr = uniq(additionalImports).join('');
47
- const summarySerializer = `export const ${summarySerializerClassName} = ${modelSerializerSignature} =>
48
- ${summarySerializerExtends}${isSTI ? '' : `\n .attribute('id')`}`;
49
- const defaultSerializer = `export const ${serializerClassName} = ${modelSerializerSignature} =>
50
- ${defaultSerializerExtends}${columnsWithTypes
51
- .map(attr => {
52
- const [name, type] = attr.split(':');
53
- if (name === undefined)
54
- return '';
55
- if (['belongsto', 'hasone', 'hasmany'].includes(camelize(type)?.toLowerCase()))
56
- return '';
57
- return `\n ${attribute(modelClassName, name, type, attr, stiBaseSerializer)}`;
58
- })
59
- .join('')}`;
43
+ const buildSerializerPair = (variantSuffix) => {
44
+ const summaryName = variantSerializerClassName(localSerializerBase, variantSuffix, 'summary');
45
+ const defaultName = variantSerializerClassName(localSerializerBase, variantSuffix, 'default');
46
+ const summaryExtends = isSTI
47
+ ? `${variantSerializerClassName(parentSerializerBase, variantSuffix, 'summary')}(${modelClassName}, ${modelSerializerArgs})`
48
+ : `DreamSerializer(${dreamSerializerArgs})`;
49
+ const defaultExtends = isSTI
50
+ ? `${variantSerializerClassName(parentSerializerBase, variantSuffix, 'default')}(${modelClassName}, ${modelSerializerArgs})`
51
+ : `${summaryName}(${stiBaseSerializer ? 'StiChildClass, ' : ''}${modelSerializerArgs})`;
52
+ const summary = `export const ${summaryName} = ${modelSerializerSignature} =>
53
+ ${summaryExtends}${isSTI ? '' : `\n .attribute('id')`}`;
54
+ const defaultBody = columnsWithTypes
55
+ .map(attr => {
56
+ const [name, type] = attr.split(':');
57
+ if (name === undefined)
58
+ return '';
59
+ if (['belongsto', 'hasone', 'hasmany'].includes(camelize(type)?.toLowerCase()))
60
+ return '';
61
+ return `\n ${attribute(modelClassName, name, type, attr, stiBaseSerializer)}`;
62
+ })
63
+ .join('');
64
+ const def = `export const ${defaultName} = ${modelSerializerSignature} =>
65
+ ${defaultExtends}${defaultBody}`;
66
+ return `${summary}\n\n${def}`;
67
+ };
68
+ const serializerBlocks = variantSuffixes.map(buildSerializerPair).join('\n\n');
60
69
  return `${dreamImport}${additionalImportsStr}${relatedModelImport}${additionalModelImports.join('')}
61
- ${summarySerializer}
62
-
63
- ${defaultSerializer}${!includeAdminSerializers
64
- ? ''
65
- : `
66
-
67
- ${summarySerializer.replace(summarySerializerClassName, adminSummarySerializerClassName)}
68
-
69
- ${defaultSerializer.replace(serializerClassName, adminSerializerClassName).replace(summarySerializerClassName, adminSummarySerializerClassName)}`}${!includeInternalSerializers
70
- ? ''
71
- : `
72
-
73
- ${summarySerializer.replace(summarySerializerClassName, internalSummarySerializerClassName)}
74
-
75
- ${defaultSerializer.replace(serializerClassName, internalSerializerClassName).replace(summarySerializerClassName, internalSummarySerializerClassName)}`}
70
+ ${serializerBlocks}
76
71
  `;
77
72
  }
73
+ function variantSerializerClassName(serializerBase, variantSuffix, kind) {
74
+ return kind === 'summary'
75
+ ? `${serializerBase}${variantSuffix}SummarySerializer`
76
+ : `${serializerBase}${variantSuffix}Serializer`;
77
+ }
78
78
  function attribute(modelClassName, name, type, attr, stiBaseSerializer) {
79
79
  if (name === 'type' && stiBaseSerializer) {
80
80
  return `.attribute('type', { openapi: { type: 'string', enum: [(StiChildClass ?? ${modelClassName}).sanitizedName] } })`;
@@ -97,11 +97,14 @@ function attributeOptionsSpecifier(type, attr) {
97
97
  return '';
98
98
  }
99
99
  }
100
- function importStatementForSerializer(originModelName, destinationModelName) {
101
- const defaultSerializer = globalClassNameFromFullyQualifiedModelName(serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(destinationModelName)));
102
- const summarySerializer = globalClassNameFromFullyQualifiedModelName(serializerNameFromFullyQualifiedModelName(fullyQualifiedModelNameToSerializerBaseName(destinationModelName), 'summary'));
100
+ function importStatementForSerializer(originModelName, destinationModelName, variantSuffixes) {
101
+ const base = fullyQualifiedModelNameToSerializerBaseName(destinationModelName);
102
+ const names = variantSuffixes.flatMap(suffix => [
103
+ globalClassNameFromFullyQualifiedModelName(variantSerializerClassName(base, suffix, 'default')),
104
+ globalClassNameFromFullyQualifiedModelName(variantSerializerClassName(base, suffix, 'summary')),
105
+ ]);
103
106
  const importFrom = absoluteDreamPath('serializers', destinationModelName);
104
- return `import { ${defaultSerializer}, ${summarySerializer} } from '${importFrom}'\n`;
107
+ return `import { ${names.join(', ')} } from '${importFrom}'\n`;
105
108
  }
106
109
  function importStatementForModel(modelClassName, fullyQualifiedModelName) {
107
110
  const importFrom = absoluteDreamPath('models', fullyQualifiedModelName);
@@ -5,8 +5,53 @@ import isDatabaseArrayColumn from '../helpers/db/types/isDatabaseArrayColumn.js'
5
5
  import CurriedOpsStatement from './curried-ops-statement.js';
6
6
  import OpsStatement from './ops-statement.js';
7
7
  const ops = {
8
+ /**
9
+ * Creates an `OpsStatement` with an arbitrary Kysely comparison operator or trigram operator.
10
+ * Use this as an escape hatch when none of the named helpers cover your use case.
11
+ *
12
+ * @param operator - Any Kysely comparison operator (e.g. `'='`, `'<'`) or trigram operator.
13
+ * @param value - The value to compare against.
14
+ * @returns An `OpsStatement` wrapping the given operator and value.
15
+ *
16
+ * @example
17
+ * User.where({ name: ops.expression('like', '%ello%') })
18
+ */
8
19
  expression: (operator, value) => new OpsStatement(operator, value),
20
+ /**
21
+ * Creates an `OpsStatement` that checks whether a JSONB column contains the given object
22
+ * using the PostgreSQL `@>` (contains) operator.
23
+ *
24
+ * @param searchObj - A plain object whose key/value pairs must be present in the JSONB column.
25
+ * @returns An `OpsStatement` using `@> <searchObj>::jsonb`.
26
+ *
27
+ * @example
28
+ * Post.where({ metadata: ops.jsonb({ published: true }) })
29
+ */
30
+ jsonb: (searchObj) => new OpsStatement('@>', sql `${searchObj}::jsonb`),
31
+ /**
32
+ * Creates an `OpsStatement` for a SQL `IN` clause, matching rows whose column value
33
+ * is one of the provided array elements.
34
+ *
35
+ * @param arr - The array of values to match against.
36
+ * @returns An `OpsStatement` using the `in` operator.
37
+ *
38
+ * @example
39
+ * User.where({ status: ops.in(['active', 'pending']) })
40
+ */
9
41
  in: (arr) => new OpsStatement('in', arr),
42
+ /**
43
+ * Creates a `CurriedOpsStatement` that checks whether a PostgreSQL array column contains
44
+ * the given value using `@> ARRAY[value]::type`. The column type is resolved at query-build
45
+ * time from the Dream model's schema.
46
+ *
47
+ * Throws `AnyRequiresArrayColumn` if the target column is not a database array type.
48
+ *
49
+ * @param value - The scalar value that must be present in the array column.
50
+ * @returns A `CurriedOpsStatement` that resolves to an `OpsStatement` once bound to a model and field.
51
+ *
52
+ * @example
53
+ * Post.where({ tags: ops.any('typescript') })
54
+ */
10
55
  any: (value) => new CurriedOpsStatement(function (dreamClass, fieldName) {
11
56
  const column = fieldName.replace(/^.*\./, '');
12
57
  if (!isDatabaseArrayColumn(dreamClass, column))
@@ -14,27 +59,226 @@ const ops = {
14
59
  const castType = cachedTypeForAttribute(dreamClass, column);
15
60
  return new OpsStatement('@>', sql `ARRAY[${sql.join([value])}]::${sql.raw(castType)}`);
16
61
  }),
62
+ /**
63
+ * Creates an `OpsStatement` using the SQL `LIKE` operator for case-sensitive pattern matching.
64
+ * Use `%` as a wildcard in the pattern string.
65
+ *
66
+ * @param like - The pattern string (e.g. `'%hello%'`).
67
+ * @returns An `OpsStatement` using the `like` operator.
68
+ *
69
+ * @example
70
+ * User.where({ name: ops.like('%alice%') })
71
+ */
17
72
  like: (like) => new OpsStatement('like', like),
73
+ /**
74
+ * Creates an `OpsStatement` using the SQL `ILIKE` operator for case-insensitive pattern matching.
75
+ * Use `%` as a wildcard in the pattern string.
76
+ *
77
+ * @param ilike - The pattern string (e.g. `'%hello%'`).
78
+ * @returns An `OpsStatement` using the `ilike` operator.
79
+ *
80
+ * @example
81
+ * User.where({ name: ops.ilike('%alice%') })
82
+ */
18
83
  ilike: (ilike) => new OpsStatement('ilike', ilike),
84
+ /**
85
+ * Creates an `OpsStatement` that matches a column against a POSIX regular expression.
86
+ * By default the match is case-sensitive (`~`); pass `{ caseInsensitive: true }` to use `~*`.
87
+ *
88
+ * @param match - The regular expression pattern.
89
+ * @param options.caseInsensitive - When `true`, uses the `~*` operator instead of `~`. Defaults to `false`.
90
+ * @returns An `OpsStatement` using `~` or `~*`.
91
+ *
92
+ * @example
93
+ * User.where({ email: ops.match('^admin', { caseInsensitive: true }) })
94
+ */
19
95
  match: (match, { caseInsensitive = false } = {}) => new OpsStatement(caseInsensitive ? '~*' : '~', match),
20
- // current
96
+ /**
97
+ * Creates an `OpsStatement` using the `=` operator for strict equality.
98
+ *
99
+ * @param equal - The value the column must equal.
100
+ * @returns An `OpsStatement` using the `=` operator.
101
+ *
102
+ * @example
103
+ * User.where({ role: ops.equal('admin') })
104
+ */
21
105
  equal: (equal) => new OpsStatement('=', equal),
106
+ /**
107
+ * Creates an `OpsStatement` using the `<` operator.
108
+ *
109
+ * @param lessThan - The value the column must be less than.
110
+ * @returns An `OpsStatement` using the `<` operator.
111
+ *
112
+ * @example
113
+ * Order.where({ total: ops.lessThan(100) })
114
+ */
22
115
  lessThan: (lessThan) => new OpsStatement('<', lessThan),
116
+ /**
117
+ * Creates an `OpsStatement` using the `<=` operator.
118
+ *
119
+ * @param lessThanOrEqualTo - The value the column must be less than or equal to.
120
+ * @returns An `OpsStatement` using the `<=` operator.
121
+ *
122
+ * @example
123
+ * Order.where({ total: ops.lessThanOrEqualTo(100) })
124
+ */
23
125
  lessThanOrEqualTo: (lessThanOrEqualTo) => new OpsStatement('<=', lessThanOrEqualTo),
126
+ /**
127
+ * Creates an `OpsStatement` using the `>` operator.
128
+ *
129
+ * @param greaterThan - The value the column must be greater than.
130
+ * @returns An `OpsStatement` using the `>` operator.
131
+ *
132
+ * @example
133
+ * Order.where({ total: ops.greaterThan(50) })
134
+ */
24
135
  greaterThan: (greaterThan) => new OpsStatement('>', greaterThan),
136
+ /**
137
+ * Creates an `OpsStatement` using the `>=` operator.
138
+ *
139
+ * @param greaterThanOrEqualTo - The value the column must be greater than or equal to.
140
+ * @returns An `OpsStatement` using the `>=` operator.
141
+ *
142
+ * @example
143
+ * Order.where({ total: ops.greaterThanOrEqualTo(50) })
144
+ */
25
145
  greaterThanOrEqualTo: (greaterThanOrEqualTo) => new OpsStatement('>=', greaterThanOrEqualTo),
146
+ /**
147
+ * Creates an `OpsStatement` for PostgreSQL trigram similarity (`%` operator).
148
+ * Rows are included when the similarity score meets or exceeds `score`.
149
+ *
150
+ * Requires the `pg_trgm` extension to be enabled.
151
+ *
152
+ * @param similarity - The string to compare against the column.
153
+ * @param options.score - Minimum similarity threshold (0–1). Defaults to `0.3`.
154
+ * @returns An `OpsStatement` using the `%` trigram operator.
155
+ *
156
+ * @example
157
+ * User.where({ name: ops.similarity('alice', { score: 0.4 }) })
158
+ */
26
159
  similarity: (similarity, { score = 0.3 } = {}) => new OpsStatement('%', similarity, { score }),
160
+ /**
161
+ * Creates an `OpsStatement` for PostgreSQL word similarity (`<%` operator).
162
+ * Rows are included when the word similarity score meets or exceeds `score`.
163
+ *
164
+ * Requires the `pg_trgm` extension to be enabled.
165
+ *
166
+ * @param similarity - The string to compare against the column.
167
+ * @param options.score - Minimum word similarity threshold (0–1). Defaults to `0.5`.
168
+ * @returns An `OpsStatement` using the `<%` trigram operator.
169
+ *
170
+ * @example
171
+ * Article.where({ title: ops.wordSimilarity('postgres', { score: 0.6 }) })
172
+ */
27
173
  wordSimilarity: (similarity, { score = 0.5 } = {}) => new OpsStatement('<%', similarity, { score }),
174
+ /**
175
+ * Creates an `OpsStatement` for PostgreSQL strict word similarity (`<<%` operator).
176
+ * Rows are included when the strict word similarity score meets or exceeds `score`.
177
+ *
178
+ * Requires the `pg_trgm` extension to be enabled.
179
+ *
180
+ * @param similarity - The string to compare against the column.
181
+ * @param options.score - Minimum strict word similarity threshold (0–1). Defaults to `0.6`.
182
+ * @returns An `OpsStatement` using the `<<%` trigram operator.
183
+ *
184
+ * @example
185
+ * Article.where({ title: ops.strictWordSimilarity('postgres', { score: 0.7 }) })
186
+ */
28
187
  strictWordSimilarity: (similarity, { score = 0.6 } = {}) => new OpsStatement('<<%', similarity, { score }),
188
+ /** Negated variants of the standard comparison operators. */
29
189
  not: {
190
+ /**
191
+ * Creates an `OpsStatement` for a SQL `NOT IN` clause, excluding rows whose column value
192
+ * is one of the provided array elements.
193
+ *
194
+ * @param arr - The array of values to exclude.
195
+ * @returns An `OpsStatement` using the `not in` operator.
196
+ *
197
+ * @example
198
+ * User.where({ status: ops.not.in(['banned', 'deleted']) })
199
+ */
30
200
  in: (arr) => new OpsStatement('not in', arr),
201
+ /**
202
+ * Creates an `OpsStatement` using the `NOT LIKE` operator for case-sensitive pattern exclusion.
203
+ *
204
+ * @param like - The pattern string (e.g. `'%spam%'`).
205
+ * @returns An `OpsStatement` using the `not like` operator.
206
+ *
207
+ * @example
208
+ * User.where({ email: ops.not.like('%@example.com') })
209
+ */
31
210
  like: (like) => new OpsStatement('not like', like),
211
+ /**
212
+ * Creates an `OpsStatement` using the `NOT ILIKE` operator for case-insensitive pattern exclusion.
213
+ *
214
+ * @param ilike - The pattern string (e.g. `'%spam%'`).
215
+ * @returns An `OpsStatement` using the `not ilike` operator.
216
+ *
217
+ * @example
218
+ * User.where({ email: ops.not.ilike('%@example.com') })
219
+ */
32
220
  ilike: (ilike) => new OpsStatement('not ilike', ilike),
221
+ /**
222
+ * Creates an `OpsStatement` that excludes rows matching a POSIX regular expression.
223
+ * By default the match is case-sensitive (`!~`); pass `{ caseInsensitive: true }` to use `!~*`.
224
+ *
225
+ * @param match - The regular expression pattern.
226
+ * @param options.caseInsensitive - When `true`, uses `!~*` instead of `!~`. Defaults to `false`.
227
+ * @returns An `OpsStatement` using `!~` or `!~*`.
228
+ *
229
+ * @example
230
+ * User.where({ email: ops.not.match('^admin', { caseInsensitive: true }) })
231
+ */
33
232
  match: (match, { caseInsensitive = false } = {}) => new OpsStatement(caseInsensitive ? '!~*' : '!~', match),
233
+ /**
234
+ * Creates an `OpsStatement` using the `!=` operator for inequality.
235
+ *
236
+ * @param equal - The value the column must not equal.
237
+ * @returns An `OpsStatement` using the `!=` operator.
238
+ *
239
+ * @example
240
+ * User.where({ role: ops.not.equal('guest') })
241
+ */
34
242
  equal: (equal) => new OpsStatement('!=', equal),
243
+ /**
244
+ * Creates an `OpsStatement` that negates `<`, equivalent to `>=`.
245
+ *
246
+ * @param lessThan - The value used as the lower bound (inclusive).
247
+ * @returns An `OpsStatement` using `>=`.
248
+ *
249
+ * @example
250
+ * Order.where({ total: ops.not.lessThan(100) }) // total >= 100
251
+ */
35
252
  lessThan: (lessThan) => new OpsStatement('>=', lessThan),
253
+ /**
254
+ * Creates an `OpsStatement` that negates `<=`, equivalent to `>`.
255
+ *
256
+ * @param lessThanOrEqualTo - The value used as the lower bound (exclusive).
257
+ * @returns An `OpsStatement` using `>`.
258
+ *
259
+ * @example
260
+ * Order.where({ total: ops.not.lessThanOrEqualTo(100) }) // total > 100
261
+ */
36
262
  lessThanOrEqualTo: (lessThanOrEqualTo) => new OpsStatement('>', lessThanOrEqualTo),
263
+ /**
264
+ * Creates an `OpsStatement` that negates `>`, equivalent to `<=`.
265
+ *
266
+ * @param greaterThan - The value used as the upper bound (inclusive).
267
+ * @returns An `OpsStatement` using `<=`.
268
+ *
269
+ * @example
270
+ * Order.where({ total: ops.not.greaterThan(50) }) // total <= 50
271
+ */
37
272
  greaterThan: (greaterThan) => new OpsStatement('<=', greaterThan),
273
+ /**
274
+ * Creates an `OpsStatement` that negates `>=`, equivalent to `<`.
275
+ *
276
+ * @param greaterThanOrEqualTo - The value used as the upper bound (exclusive).
277
+ * @returns An `OpsStatement` using `<`.
278
+ *
279
+ * @example
280
+ * Order.where({ total: ops.not.greaterThanOrEqualTo(50) }) // total < 50
281
+ */
38
282
  greaterThanOrEqualTo: (greaterThanOrEqualTo) => new OpsStatement('<', greaterThanOrEqualTo),
39
283
  },
40
284
  };
@@ -17,6 +17,7 @@ export default class DreamBin {
17
17
  adminSerializers?: boolean;
18
18
  internalSerializers?: boolean;
19
19
  modelName?: string;
20
+ softDelete?: boolean;
20
21
  }): Promise<void>;
21
22
  static generateStiChild(fullyQualifiedModelName: string, fullyQualifiedParentName: string, columnsWithTypes: string[], options: {
22
23
  serializer: boolean;
@@ -38,6 +38,13 @@ export default class DreamCLI {
38
38
  * instead of deriving the class name from the fully qualified model name.
39
39
  */
40
40
  modelName?: string | undefined;
41
+ /**
42
+ * When true (and the generated model is NOT an STI child), decorates
43
+ * the model with `@SoftDelete()` and auto-emits a nullable
44
+ * `deleted_at` column. Defaults to false at this programmatic entry
45
+ * point — the CLI layer opts users in by default.
46
+ */
47
+ softDelete?: boolean;
41
48
  };
42
49
  fullyQualifiedParentName?: string | undefined;
43
50
  }): Promise<void>;
@@ -6,6 +6,14 @@ export interface GenerateDreamOptions {
6
6
  includeInternalSerializers?: boolean;
7
7
  tableName?: string | undefined;
8
8
  modelName?: string | undefined;
9
+ /**
10
+ * When true (and the generated model is NOT an STI child), decorates the
11
+ * model with `@SoftDelete()` and auto-emits a nullable `deleted_at`
12
+ * column in the migration and a `deletedAt` field on the model. Defaults
13
+ * to false at this level — the CLI layer opts users in by default and
14
+ * allows opt-out via `--no-soft-delete`.
15
+ */
16
+ softDelete?: boolean;
9
17
  }
10
18
  export default function generateDream({ fullyQualifiedModelName, columnsWithTypes, options, fullyQualifiedParentName, }: {
11
19
  fullyQualifiedModelName: string;
@@ -9,7 +9,15 @@ interface GenerateDreamContentOptions {
9
9
  tableName?: string | undefined;
10
10
  /** Model class name, computed once via modelClassNameFrom in the orchestrator. */
11
11
  modelClassName: string;
12
+ /**
13
+ * When true, decorates the generated model with `@SoftDelete()` and adds a
14
+ * `deletedAt` field to the model. Ignored for STI children (the `@SoftDelete()`
15
+ * decorator is incompatible with STI children).
16
+ */
17
+ softDelete?: boolean;
12
18
  }
19
+ export declare function hasExplicitColumn(columnsWithTypes: string[], name: string): boolean;
20
+ export declare function filterAutoGeneratedTimestampColumns(columnsWithTypes: string[]): string[];
13
21
  export interface ModelConfig {
14
22
  fullyQualifiedModelName: string;
15
23
  modelClassName: string;
@@ -29,7 +37,9 @@ export interface AttributeProcessingResult {
29
37
  }
30
38
  export default function generateDreamContent(options: GenerateDreamContentOptions): string;
31
39
  export declare function createModelConfig(options: GenerateDreamContentOptions): ModelConfig;
32
- export declare function createImportConfig(config: ModelConfig, options: GenerateDreamContentOptions): ImportConfig;
40
+ export declare function createImportConfig(config: ModelConfig, options: GenerateDreamContentOptions, { includeSoftDelete }: {
41
+ includeSoftDelete: boolean;
42
+ }): ImportConfig;
33
43
  export declare function processAttributes(columnsWithTypes: string[], modelClassName: string): AttributeProcessingResult & {
34
44
  formattedFields: string;
35
45
  formattedDecorators: string;
@@ -1,4 +1,4 @@
1
- export default function generateMigration({ migrationName, columnsWithTypes, connectionName, fullyQualifiedModelName, fullyQualifiedParentName, tableName: explicitTableName, modelClassName, }: {
1
+ export default function generateMigration({ migrationName, columnsWithTypes, connectionName, fullyQualifiedModelName, fullyQualifiedParentName, tableName: explicitTableName, modelClassName, softDelete, }: {
2
2
  migrationName: string;
3
3
  columnsWithTypes: string[];
4
4
  connectionName: string;
@@ -11,4 +11,10 @@ export default function generateMigration({ migrationName, columnsWithTypes, con
11
11
  * Omitted for standalone `g:migration` commands.
12
12
  */
13
13
  modelClassName?: string | undefined;
14
+ /**
15
+ * When true (and not an STI child), the generated `createTable` migration
16
+ * includes a nullable `deleted_at` column alongside the standard
17
+ * `created_at` / `updated_at` timestamps.
18
+ */
19
+ softDelete?: boolean;
14
20
  }): Promise<void>;
@@ -1,10 +1,16 @@
1
1
  import { LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
2
- export default function generateMigrationContent({ connectionName, table, columnsWithTypes, primaryKeyType, createOrAlter, stiChildClassName, }?: {
2
+ export default function generateMigrationContent({ connectionName, table, columnsWithTypes, primaryKeyType, createOrAlter, stiChildClassName, softDelete, }?: {
3
3
  connectionName?: string;
4
4
  table?: string | undefined;
5
5
  columnsWithTypes?: string[] | undefined;
6
6
  primaryKeyType?: LegacyCompatiblePrimaryKeyType | undefined;
7
7
  createOrAlter?: 'create' | 'alter' | undefined;
8
8
  stiChildClassName?: string | undefined;
9
+ /**
10
+ * When true (and creating a new table), auto-emits a nullable `deleted_at`
11
+ * column alongside `created_at` / `updated_at`. Ignored in alter mode and
12
+ * for STI child migrations.
13
+ */
14
+ softDelete?: boolean;
9
15
  }): string;
10
16
  export declare function optionalFromDescriptors(descriptors: string[]): boolean;