@spinajs/orm 2.0.499 → 2.0.501

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.
package/lib/cjs/schema.js CHANGED
@@ -66,7 +66,7 @@ function buildModelJsonSchema(descriptor, kind = 'request') {
66
66
  if (!col || col.Ignore || !col.Name || hidden.has(col.Name)) {
67
67
  continue;
68
68
  }
69
- properties[col.Name] = columnToSchema(col, overrides);
69
+ properties[col.Name] = columnToSchema(col, overrides, descriptor.Converters?.get(col.Name)?.Class);
70
70
  if (!col.Nullable && !col.AutoIncrement) {
71
71
  required.push(col.Name);
72
72
  }
@@ -89,21 +89,74 @@ function buildModelJsonSchema(descriptor, kind = 'request') {
89
89
  function driverResponseTypes(descriptor) {
90
90
  return descriptor.Driver?.ResponseSchemaTypes ?? {};
91
91
  }
92
+ /**
93
+ * Is `ctor` the converter class called `name`, or a subclass of it?
94
+ *
95
+ * Matched by NAME along the prototype chain rather than with `instanceof`: this module sits on
96
+ * the descriptor-building path and importing the converter classes from `interfaces.js` as
97
+ * VALUES would drag the query-builder / driver / model graph in with them.
98
+ *
99
+ * The chain walk is what makes a driver's own converter count. orm-mssql registers
100
+ * `MsSqlDatetimeValueConverter` **as** `DatetimeValueConverter`, so what the container hands back
101
+ * for an `@CreatedAt()` column on that connection is a subclass - an exact name comparison sees
102
+ * `MsSqlDatetimeValueConverter` and misses it.
103
+ *
104
+ * @param ctor - converter class to test ( or the constructor of a converter instance )
105
+ * @param name - base converter class name to look for
106
+ */
107
+ function isConverterNamed(ctor, name) {
108
+ let current = ctor;
109
+ while (typeof current === 'function') {
110
+ if (current.name === name) {
111
+ return true;
112
+ }
113
+ current = Object.getPrototypeOf(current);
114
+ }
115
+ return false;
116
+ }
92
117
  /**
93
118
  * Maps a column descriptor to a JSON-schema property based on its SQL type.
94
119
  * Adds `maxLength`, `description` and `nullable` when the column has them.
95
120
  *
96
121
  * @param col - column to describe
97
122
  * @param overrides - per-type shapes that win over the shared map ( response flavour only )
123
+ * @param declaredConverter - converter class the model's decorators asked for, from
124
+ * `descriptor.Converters` ( `@DateTime()`, `@CreatedAt()`, ... )
98
125
  */
99
- function columnToSchema(col, overrides = {}) {
100
- const converter = col.Converter?.constructor?.name;
126
+ function columnToSchema(col, overrides = {}, declaredConverter) {
127
+ // The declared class wins over the resolved instance: a decorator is an explicit statement
128
+ // about the property, while the instance is only there when the container had the converter
129
+ // registered on that connection.
130
+ const converter = declaredConverter ?? col.Converter?.constructor;
101
131
  const schema = { ...(overrides[col.Type] ?? SQL_TYPE_TO_SCHEMA[col.Type] ?? { type: 'string' }) };
102
- if (converter === 'BooleanValueConverter') {
132
+ if (isConverterNamed(converter, 'BooleanValueConverter')) {
103
133
  schema.type = 'boolean';
104
134
  delete schema.format;
105
135
  }
106
- if (schema.type === 'string' && col.MaxLength > 0) {
136
+ /**
137
+ * A datetime converter is attached by @DateTime(), @CreatedAt(), @UpdatedAt(), @SoftDelete()
138
+ * and @Archived(), all of which reject any property that is not a Luxon `DateTime`. So the
139
+ * value travels as an ISO-8601 string whatever the STORAGE type is, and the SQL type alone
140
+ * does not say so:
141
+ * - sqlite compiles `dateTime()` down to TEXT and `PRAGMA table_info` reports TEXT back,
142
+ * - a legacy MySQL table may keep timestamps in a VARCHAR or an INT.
143
+ * Both fell through `SQL_TYPE_TO_SCHEMA` to a bare `{ type: 'string' }` ( or an integer ),
144
+ * and `format: date-time` is the ONLY signal downstream: a generated client reads such a
145
+ * property as plain text and skips the date conversion entirely.
146
+ *
147
+ * A `date` column keeps `format: date`. The decorator says how the value is CONVERTED, not
148
+ * that the database suddenly stores a time of day, and `date` is a date-time to every
149
+ * generator that cares.
150
+ */
151
+ const isDateTime = isConverterNamed(converter, 'DatetimeValueConverter');
152
+ if (isDateTime && schema.format !== 'date') {
153
+ schema.type = 'string';
154
+ schema.format = 'date-time';
155
+ }
156
+ // `maxLength` copied from a VARCHAR that happens to hold a timestamp describes the storage,
157
+ // not the contract - and published on a response it lets a generated validator reject a
158
+ // perfectly good ISO-8601 string that is a few characters longer than the column.
159
+ if (schema.type === 'string' && !isDateTime && col.MaxLength > 0) {
107
160
  schema.maxLength = col.MaxLength;
108
161
  }
109
162
  if (col.Comment) {
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":";;;AAAA,yCAAwC;AAGxC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,kBAAkB,GAAwB;IAC9C,CAAC,qBAAU,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC9C,CAAC,qBAAU,CAAC,aAAa,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC/C,CAAC,qBAAU,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAChD,CAAC,qBAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IACzC,CAAC,qBAAU,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7C,CAAC,qBAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACxC,CAAC,qBAAU,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACtC,CAAC,qBAAU,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACvC,CAAC,qBAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACpC,CAAC,qBAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IACzC,CAAC,qBAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;IACrD,CAAC,qBAAU,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;IAC/D,gGAAgG;IAChG,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;IACjD,CAAC,qBAAU,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;IAC/D,CAAC,qBAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACrC,CAAC,qBAAU,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;CAC/D,CAAC;AAQF;;;;;;;;;;;;;;;GAeG;AACH,8BAAqC,UAA4B,EAAE,IAAI,GAAoB,SAAS;IAClG,MAAM,UAAU,GAAwB,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IAC1F,MAAM,SAAS,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5D,SAAS;QACX,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACxC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IACnD,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,mBAAmB,CAAC,UAA4B;IACvD,OAAQ,UAAU,CAAC,MAA2E,EAAE,mBAAmB,IAAI,EAAE,CAAC;AAC5H,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,GAAsB,EAAE,SAAS,GAAwB,EAAE;IACjF,MAAM,SAAS,GAAI,GAAG,CAAC,SAAoE,EAAE,WAAW,EAAE,IAAI,CAAC;IAE/G,MAAM,MAAM,GAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAEvG,IAAI,SAAS,KAAK,uBAAuB,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC;QACxB,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC;IACnC,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"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"}
package/lib/mjs/schema.js CHANGED
@@ -63,7 +63,7 @@ export function buildModelJsonSchema(descriptor, kind = 'request') {
63
63
  if (!col || col.Ignore || !col.Name || hidden.has(col.Name)) {
64
64
  continue;
65
65
  }
66
- properties[col.Name] = columnToSchema(col, overrides);
66
+ properties[col.Name] = columnToSchema(col, overrides, descriptor.Converters?.get(col.Name)?.Class);
67
67
  if (!col.Nullable && !col.AutoIncrement) {
68
68
  required.push(col.Name);
69
69
  }
@@ -86,21 +86,74 @@ export function buildModelJsonSchema(descriptor, kind = 'request') {
86
86
  function driverResponseTypes(descriptor) {
87
87
  return descriptor.Driver?.ResponseSchemaTypes ?? {};
88
88
  }
89
+ /**
90
+ * Is `ctor` the converter class called `name`, or a subclass of it?
91
+ *
92
+ * Matched by NAME along the prototype chain rather than with `instanceof`: this module sits on
93
+ * the descriptor-building path and importing the converter classes from `interfaces.js` as
94
+ * VALUES would drag the query-builder / driver / model graph in with them.
95
+ *
96
+ * The chain walk is what makes a driver's own converter count. orm-mssql registers
97
+ * `MsSqlDatetimeValueConverter` **as** `DatetimeValueConverter`, so what the container hands back
98
+ * for an `@CreatedAt()` column on that connection is a subclass - an exact name comparison sees
99
+ * `MsSqlDatetimeValueConverter` and misses it.
100
+ *
101
+ * @param ctor - converter class to test ( or the constructor of a converter instance )
102
+ * @param name - base converter class name to look for
103
+ */
104
+ function isConverterNamed(ctor, name) {
105
+ let current = ctor;
106
+ while (typeof current === 'function') {
107
+ if (current.name === name) {
108
+ return true;
109
+ }
110
+ current = Object.getPrototypeOf(current);
111
+ }
112
+ return false;
113
+ }
89
114
  /**
90
115
  * Maps a column descriptor to a JSON-schema property based on its SQL type.
91
116
  * Adds `maxLength`, `description` and `nullable` when the column has them.
92
117
  *
93
118
  * @param col - column to describe
94
119
  * @param overrides - per-type shapes that win over the shared map ( response flavour only )
120
+ * @param declaredConverter - converter class the model's decorators asked for, from
121
+ * `descriptor.Converters` ( `@DateTime()`, `@CreatedAt()`, ... )
95
122
  */
96
- function columnToSchema(col, overrides = {}) {
97
- const converter = col.Converter?.constructor?.name;
123
+ function columnToSchema(col, overrides = {}, declaredConverter) {
124
+ // The declared class wins over the resolved instance: a decorator is an explicit statement
125
+ // about the property, while the instance is only there when the container had the converter
126
+ // registered on that connection.
127
+ const converter = declaredConverter ?? col.Converter?.constructor;
98
128
  const schema = { ...(overrides[col.Type] ?? SQL_TYPE_TO_SCHEMA[col.Type] ?? { type: 'string' }) };
99
- if (converter === 'BooleanValueConverter') {
129
+ if (isConverterNamed(converter, 'BooleanValueConverter')) {
100
130
  schema.type = 'boolean';
101
131
  delete schema.format;
102
132
  }
103
- if (schema.type === 'string' && col.MaxLength > 0) {
133
+ /**
134
+ * A datetime converter is attached by @DateTime(), @CreatedAt(), @UpdatedAt(), @SoftDelete()
135
+ * and @Archived(), all of which reject any property that is not a Luxon `DateTime`. So the
136
+ * value travels as an ISO-8601 string whatever the STORAGE type is, and the SQL type alone
137
+ * does not say so:
138
+ * - sqlite compiles `dateTime()` down to TEXT and `PRAGMA table_info` reports TEXT back,
139
+ * - a legacy MySQL table may keep timestamps in a VARCHAR or an INT.
140
+ * Both fell through `SQL_TYPE_TO_SCHEMA` to a bare `{ type: 'string' }` ( or an integer ),
141
+ * and `format: date-time` is the ONLY signal downstream: a generated client reads such a
142
+ * property as plain text and skips the date conversion entirely.
143
+ *
144
+ * A `date` column keeps `format: date`. The decorator says how the value is CONVERTED, not
145
+ * that the database suddenly stores a time of day, and `date` is a date-time to every
146
+ * generator that cares.
147
+ */
148
+ const isDateTime = isConverterNamed(converter, 'DatetimeValueConverter');
149
+ if (isDateTime && schema.format !== 'date') {
150
+ schema.type = 'string';
151
+ schema.format = 'date-time';
152
+ }
153
+ // `maxLength` copied from a VARCHAR that happens to hold a timestamp describes the storage,
154
+ // not the contract - and published on a response it lets a generated validator reject a
155
+ // perfectly good ISO-8601 string that is a few characters longer than the column.
156
+ if (schema.type === 'string' && !isDateTime && col.MaxLength > 0) {
104
157
  schema.maxLength = col.MaxLength;
105
158
  }
106
159
  if (col.Comment) {
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"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"}