@spinajs/session-provider-db 2.0.489 → 2.0.490

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 (47) hide show
  1. package/lib/cjs/index.d.ts +2 -0
  2. package/lib/cjs/index.d.ts.map +1 -1
  3. package/lib/cjs/index.js +33 -1
  4. package/lib/cjs/index.js.map +1 -1
  5. package/lib/cjs/migration-support.d.ts +43 -0
  6. package/lib/cjs/migration-support.d.ts.map +1 -0
  7. package/lib/cjs/migration-support.js +97 -0
  8. package/lib/cjs/migration-support.js.map +1 -0
  9. package/lib/cjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.d.ts.map +1 -1
  10. package/lib/cjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js +8 -0
  11. package/lib/cjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js.map +1 -1
  12. package/lib/cjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.d.ts +101 -0
  13. package/lib/cjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.d.ts.map +1 -0
  14. package/lib/cjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.js +144 -0
  15. package/lib/cjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.js.map +1 -0
  16. package/lib/cjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.d.ts +68 -0
  17. package/lib/cjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.d.ts.map +1 -0
  18. package/lib/cjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.js +95 -0
  19. package/lib/cjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.js.map +1 -0
  20. package/lib/cjs/models/DbSession.d.ts +15 -0
  21. package/lib/cjs/models/DbSession.d.ts.map +1 -1
  22. package/lib/cjs/models/DbSession.js.map +1 -1
  23. package/lib/mjs/index.d.ts +2 -0
  24. package/lib/mjs/index.d.ts.map +1 -1
  25. package/lib/mjs/index.js +33 -1
  26. package/lib/mjs/index.js.map +1 -1
  27. package/lib/mjs/migration-support.d.ts +43 -0
  28. package/lib/mjs/migration-support.d.ts.map +1 -0
  29. package/lib/mjs/migration-support.js +91 -0
  30. package/lib/mjs/migration-support.js.map +1 -0
  31. package/lib/mjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.d.ts.map +1 -1
  32. package/lib/mjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js +8 -0
  33. package/lib/mjs/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js.map +1 -1
  34. package/lib/mjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.d.ts +101 -0
  35. package/lib/mjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.d.ts.map +1 -0
  36. package/lib/mjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.js +141 -0
  37. package/lib/mjs/migrations/UserSessionDataJson_2026_07_31_00_00_00.js.map +1 -0
  38. package/lib/mjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.d.ts +68 -0
  39. package/lib/mjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.d.ts.map +1 -0
  40. package/lib/mjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.js +92 -0
  41. package/lib/mjs/migrations/UserSessionTimestamps_2026_07_31_00_00_01.js.map +1 -0
  42. package/lib/mjs/models/DbSession.d.ts +15 -0
  43. package/lib/mjs/models/DbSession.d.ts.map +1 -1
  44. package/lib/mjs/models/DbSession.js.map +1 -1
  45. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  46. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  47. package/package.json +10 -10
@@ -2,6 +2,8 @@ import { SessionProvider, ISession } from '@spinajs/rbac';
2
2
  import { Log } from '@spinajs/log';
3
3
  export * from './models/DbSession.js';
4
4
  export * from './migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js';
5
+ export * from './migrations/UserSessionDataJson_2026_07_31_00_00_00.js';
6
+ export * from './migrations/UserSessionTimestamps_2026_07_31_00_00_01.js';
5
7
  /**
6
8
  * Relational-db backed session store. Conforms to the `@spinajs/rbac`
7
9
  * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAqD,MAAM,eAAe,CAAC;AAE7G,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAM3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAE9E;;;;;GAKG;AACH,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IAIH,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAErB,OAAO;IAWpB;;;;;;OAMG;IACU,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBjC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBpD,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtC,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAM/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,gBAAgB;CAMzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAqD,MAAM,eAAe,CAAC;AAE7G,OAAO,EAAU,GAAG,EAAE,MAAM,cAAc,CAAC;AAM3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+DAA+D,CAAC;AAC9E,cAAc,yDAAyD,CAAC;AACxE,cAAc,2DAA2D,CAAC;AAE1E;;;;;GAKG;AACH,qBACa,cAAe,SAAQ,eAAe;IAEjD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IAIH,SAAS,CAAC,eAAe,EAAE,MAAM,CAAC;IAErB,OAAO;IAWpB;;;;;;OAMG;IACU,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAgBjC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBpD,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBtC,KAAK,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAM/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,gBAAgB;CAMzB"}
package/lib/cjs/index.js CHANGED
@@ -33,6 +33,8 @@ const configuration_1 = require("@spinajs/configuration");
33
33
  const luxon_1 = require("luxon");
34
34
  __exportStar(require("./models/DbSession.js"), exports);
35
35
  __exportStar(require("./migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.js"), exports);
36
+ __exportStar(require("./migrations/UserSessionDataJson_2026_07_31_00_00_00.js"), exports);
37
+ __exportStar(require("./migrations/UserSessionTimestamps_2026_07_31_00_00_01.js"), exports);
36
38
  /**
37
39
  * Relational-db backed session store. Conforms to the `@spinajs/rbac`
38
40
  * `SessionProvider` contract: ownership is the numeric `UserId`, expiration is
@@ -138,7 +140,7 @@ let DbSessionStore = class DbSessionStore extends rbac_1.SessionProvider {
138
140
  UserId: row.UserId,
139
141
  Creation: row.CreatedAt,
140
142
  Expiration: row.Expiration ?? undefined,
141
- Data: (0, rbac_1.decodeSessionData)(row.Data),
143
+ Data: (0, rbac_1.decodeSessionData)(sessionDataFromColumn(row.Data)),
142
144
  });
143
145
  }
144
146
  expirationEquals(a, b) {
@@ -162,4 +164,34 @@ __decorate([
162
164
  exports.DbSessionStore = DbSessionStore = __decorate([
163
165
  (0, di_1.Injectable)(rbac_1.SessionProvider)
164
166
  ], DbSessionStore);
167
+ /**
168
+ * Presents whatever the driver hands back for `user_sessions.Data` in one of the
169
+ * two shapes {@link decodeSessionData} understands - a JSON string, or an
170
+ * already-parsed object graph.
171
+ *
172
+ * `Data` is a MySQL `json` column, so mysql2 parses it for us and this function
173
+ * passes the OBJECT straight through: no `JSON.stringify` / `JSON.parse`
174
+ * round-trip, the decoder walks the graph natively. Strings pass through just as
175
+ * untouched - sqlite has no json type and returns the stored text, and a
176
+ * connection configured otherwise (`typeCast`, an older column, a text-typed
177
+ * table that has not run the converging migration yet) may still yield one.
178
+ *
179
+ * The only value actually converted is a `Buffer`: a blob-ish column or a driver
180
+ * in binary mode delivers one, and neither the object walk nor `JSON.parse` can
181
+ * read it. Note it is decoded to text rather than handed over as an object -
182
+ * treating a Buffer as an object graph would walk its byte indices and decode to
183
+ * an empty session.
184
+ *
185
+ * The write path is untouched: `encodeSessionData` still stores a string, which
186
+ * a `json` column accepts verbatim (mysql2 does NOT auto-serialize objects into
187
+ * json columns, and `DbSession.Data` deliberately carries no `@Json()`
188
+ * decorator - the ORM's JsonValueConverter would `JSON.stringify` the already
189
+ * encoded string and double-encode every session).
190
+ */
191
+ function sessionDataFromColumn(data) {
192
+ if (Buffer.isBuffer(data)) {
193
+ return data.toString('utf8');
194
+ }
195
+ return data;
196
+ }
165
197
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { OrmDriver } from '@spinajs/orm';
2
+ /**
3
+ * True when the connection speaks MySQL's DDL dialect. See {@link MYSQL_DRIVERS}.
4
+ *
5
+ * @param connection - the migration's connection
6
+ */
7
+ export declare function isMySqlDialect(connection: OrmDriver): boolean;
8
+ /**
9
+ * Reduces a driver-reported `NativeType` to its bare type name, lower-cased.
10
+ *
11
+ * `IColumnDescriptor.NativeType` is documented as the FULL database type - MySQL
12
+ * reports `information_schema.DATA_TYPE` (already bare: `varchar`, `text`,
13
+ * `json`, `date`), but sqlite reports the declared type verbatim, so
14
+ * `VARCHAR(36)` and `INT(10) UNSIGNED` both occur. Comparing raw strings would
15
+ * therefore miss exactly the databases the probe exists to recognise.
16
+ *
17
+ * @param nativeType - whatever the driver reported
18
+ */
19
+ export declare function normalizeNativeType(nativeType: string): string;
20
+ /**
21
+ * True when the (normalized) type is one of the text-family types listed in
22
+ * {@link TEXT_FAMILY}.
23
+ *
24
+ * @param nativeType - a type name, normalized or not
25
+ */
26
+ export declare function isTextFamily(nativeType: string): boolean;
27
+ /**
28
+ * Normalized native type of one column, or `null` when it cannot be established.
29
+ *
30
+ * `null` means "do not touch anything": the table is not described, the column
31
+ * is absent, or the driver's `tableInfo()` refused/failed. A migration that
32
+ * cannot see the current state must SKIP, never guess - a throw here would be
33
+ * recorded as a failed migration, and `assertNoFailed()` then blocks every
34
+ * subsequent migration on that connection until somebody edits the tracking
35
+ * table by hand. On a service that migrates at boot that is an outage, and the
36
+ * thing being probed is a type conversion nobody is waiting for.
37
+ *
38
+ * @param connection - the migration's connection
39
+ * @param table - table name
40
+ * @param column - column name, compared case-insensitively
41
+ */
42
+ export declare function columnNativeType(connection: OrmDriver, table: string, column: string): Promise<string | null>;
43
+ //# sourceMappingURL=migration-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-support.d.ts","sourceRoot":"","sources":["../../src/migration-support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAiCzC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAE7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBnH"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMySqlDialect = isMySqlDialect;
4
+ exports.normalizeNativeType = normalizeNativeType;
5
+ exports.isTextFamily = isTextFamily;
6
+ exports.columnNativeType = columnNativeType;
7
+ /**
8
+ * Shared probes for the converging migrations in `./migrations`.
9
+ *
10
+ * Lives OUTSIDE `src/migrations` on purpose: `MigrationSource` globs that
11
+ * directory and imports every `.js` it finds, and a module that is not a
12
+ * migration has no business being pulled into that scan.
13
+ */
14
+ /**
15
+ * Driver names (the `@Injectable(...)` keys the mysql package registers, which
16
+ * is what `db.Connections[n].Driver` carries) whose dialect understands
17
+ * `ALTER TABLE ... MODIFY <col> <type>` and has a native `JSON` column type.
18
+ *
19
+ * This gate is not decoration. `MODIFY` is MySQL/MariaDB syntax - MSSQL spells
20
+ * it `ALTER COLUMN` and has no `JSON` type at all, sqlite has neither - so
21
+ * emitting the statement anywhere else is a syntax error, i.e. a FAILED
22
+ * migration, i.e. `assertNoFailed()` blocking every future migration on that
23
+ * connection. Every other dialect stores the payload as text and the read path
24
+ * (`decodeSessionData`) already handles the string shape, so skipping there is
25
+ * not a compromise: there is genuinely nothing to converge.
26
+ */
27
+ const MYSQL_DRIVERS = ['orm-driver-mysql', 'orm-driver-mysql-ssh'];
28
+ /**
29
+ * The text-family native types a legacy `user_sessions.Data` can carry. A
30
+ * column of any of these is the state the JSON conversion exists to fix;
31
+ * anything else (`json` on a converged or fresh database, or something nobody
32
+ * anticipated) is left alone.
33
+ */
34
+ const TEXT_FAMILY = ['text', 'tinytext', 'mediumtext', 'longtext', 'varchar', 'nvarchar'];
35
+ /**
36
+ * True when the connection speaks MySQL's DDL dialect. See {@link MYSQL_DRIVERS}.
37
+ *
38
+ * @param connection - the migration's connection
39
+ */
40
+ function isMySqlDialect(connection) {
41
+ return MYSQL_DRIVERS.includes(connection.Options?.Driver);
42
+ }
43
+ /**
44
+ * Reduces a driver-reported `NativeType` to its bare type name, lower-cased.
45
+ *
46
+ * `IColumnDescriptor.NativeType` is documented as the FULL database type - MySQL
47
+ * reports `information_schema.DATA_TYPE` (already bare: `varchar`, `text`,
48
+ * `json`, `date`), but sqlite reports the declared type verbatim, so
49
+ * `VARCHAR(36)` and `INT(10) UNSIGNED` both occur. Comparing raw strings would
50
+ * therefore miss exactly the databases the probe exists to recognise.
51
+ *
52
+ * @param nativeType - whatever the driver reported
53
+ */
54
+ function normalizeNativeType(nativeType) {
55
+ return String(nativeType).toLowerCase().split('(')[0].trim().split(/\s+/)[0];
56
+ }
57
+ /**
58
+ * True when the (normalized) type is one of the text-family types listed in
59
+ * {@link TEXT_FAMILY}.
60
+ *
61
+ * @param nativeType - a type name, normalized or not
62
+ */
63
+ function isTextFamily(nativeType) {
64
+ return TEXT_FAMILY.includes(normalizeNativeType(nativeType));
65
+ }
66
+ /**
67
+ * Normalized native type of one column, or `null` when it cannot be established.
68
+ *
69
+ * `null` means "do not touch anything": the table is not described, the column
70
+ * is absent, or the driver's `tableInfo()` refused/failed. A migration that
71
+ * cannot see the current state must SKIP, never guess - a throw here would be
72
+ * recorded as a failed migration, and `assertNoFailed()` then blocks every
73
+ * subsequent migration on that connection until somebody edits the tracking
74
+ * table by hand. On a service that migrates at boot that is an outage, and the
75
+ * thing being probed is a type conversion nobody is waiting for.
76
+ *
77
+ * @param connection - the migration's connection
78
+ * @param table - table name
79
+ * @param column - column name, compared case-insensitively
80
+ */
81
+ async function columnNativeType(connection, table, column) {
82
+ let columns;
83
+ try {
84
+ columns = await connection.tableInfo(table);
85
+ }
86
+ catch {
87
+ // e.g. the mysql driver throws when the connection carries no Database, and
88
+ // a driver may not implement tableInfo usefully at all.
89
+ return null;
90
+ }
91
+ const found = columns?.find((c) => c.Name?.toLowerCase() === column.toLowerCase());
92
+ if (!found?.NativeType) {
93
+ return null;
94
+ }
95
+ return normalizeNativeType(found.NativeType);
96
+ }
97
+ //# sourceMappingURL=migration-support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-support.js","sourceRoot":"","sources":["../../src/migration-support.ts"],"names":[],"mappings":";;AAsCA,wCAEC;AAaD,kDAEC;AAQD,oCAEC;AAiBD,4CAkBC;AAlGD;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAAG,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAE1F;;;;GAIG;AACH,SAAgB,cAAc,CAAC,UAAqB;IAClD,OAAO,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB,CAAC,UAAkB;IACpD,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,UAAkB;IAC7C,OAAO,WAAW,CAAC,QAAQ,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACI,KAAK,UAAU,gBAAgB,CAAC,UAAqB,EAAE,KAAa,EAAE,MAAc;IACzF,IAAI,OAAO,CAAC;IAEZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,wDAAwD;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAEnF,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserSessionDBSqlMigration_2022_06_28_01_20_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,SAAS,EAAqB,MAAM,cAAc,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,6CAA8C,SAAQ,YAAY;IAChE,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxC,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAC/C"}
1
+ {"version":3,"file":"UserSessionDBSqlMigration_2022_06_28_01_20_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,SAAS,EAAqB,MAAM,cAAc,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,6CAA8C,SAAQ,YAAY;IAChE,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BxC,IAAI,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAC/C"}
@@ -41,6 +41,14 @@ let UserSessionDBSqlMigration_2022_06_28_01_20_00 = class UserSessionDBSqlMigrat
41
41
  table.string('SessionId', 36).primaryKey().notNull();
42
42
  table.dateTime('CreatedAt').notNull();
43
43
  table.dateTime('Expiration');
44
+ // JSON is the intended type, so a fresh install gets it straight away and never needs the
45
+ // converging migration (`UserSessionDataJson_2026_07_31_00_00_00`) to do any work. Deployed
46
+ // databases created before this migration existed carry a text-family column - the guard
47
+ // above means the type declared here has never run against them - and that migration is what
48
+ // brings them here.
49
+ //
50
+ // The read path consumes both shapes on purpose: mysql2 returns a json column as a parsed
51
+ // object, sqlite (which has no json type) returns the stored text. See `decodeSessionData`.
44
52
  table.json('Data').notNull();
45
53
  table.int('UserId').notNull();
46
54
  table.foreignKey('UserId').references('users', 'Id').onDelete(orm_1.ReferentialAction.Cascade);
@@ -1 +1 @@
1
- {"version":3,"file":"UserSessionDBSqlMigration_2022_06_28_01_20_00.js","sourceRoot":"","sources":["../../../src/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sCAAqF;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEI,IAAM,6CAA6C,GAAnD,MAAM,6CAA8C,SAAQ,kBAAY;IACtE,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,6FAA6F;QAC7F,uEAAuE;QACvE,IAAI,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/D,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC;YACrD,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7B,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YAE9B,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,uBAAiB,CAAC,OAAO,CAAC,CAAC;QAC3F,CAAC,CAAC,CAAC;QAEH,gGAAgG;QAChG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtH,CAAC;IAED,qCAAqC;IAC9B,KAAK,CAAC,IAAI,CAAC,CAAY,IAAkB,CAAC;CAClD,CAAA;AAxBY,sGAA6C;wDAA7C,6CAA6C;IADzD,IAAA,eAAS,EAAC,6BAA6B,CAAC;GAC5B,6CAA6C,CAwBzD"}
1
+ {"version":3,"file":"UserSessionDBSqlMigration_2022_06_28_01_20_00.js","sourceRoot":"","sources":["../../../src/migrations/UserSessionDBSqlMigration_2022_06_28_01_20_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sCAAqF;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEI,IAAM,6CAA6C,GAAnD,MAAM,6CAA8C,SAAQ,kBAAY;IACtE,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,6FAA6F;QAC7F,uEAAuE;QACvE,IAAI,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/D,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC;YACrD,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7B,0FAA0F;YAC1F,4FAA4F;YAC5F,yFAAyF;YACzF,6FAA6F;YAC7F,oBAAoB;YACpB,EAAE;YACF,0FAA0F;YAC1F,4FAA4F;YAC5F,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7B,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YAE9B,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,uBAAiB,CAAC,OAAO,CAAC,CAAC;QAC3F,CAAC,CAAC,CAAC;QAEH,gGAAgG;QAChG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtH,CAAC;IAED,qCAAqC;IAC9B,KAAK,CAAC,IAAI,CAAC,CAAY,IAAkB,CAAC;CAClD,CAAA;AAhCY,sGAA6C;wDAA7C,6CAA6C;IADzD,IAAA,eAAS,EAAC,6BAA6B,CAAC;GAC5B,6CAA6C,CAgCzD"}
@@ -0,0 +1,101 @@
1
+ import { OrmMigration, OrmDriver } from '@spinajs/orm';
2
+ /**
3
+ * Converts an EXISTING text-typed `user_sessions.Data` to a native MySQL `json`
4
+ * column, so the read path receives a parsed object graph instead of text.
5
+ *
6
+ * Databases created before the create-path migration
7
+ * (`UserSessionDBSqlMigration_2022_06_28_01_20_00`) declared `json` - i.e. every
8
+ * deployment - carry `Data text NOT NULL`. The create migration returns early
9
+ * when the table is already there, so the type it declares has never reached
10
+ * them. Fresh installs already get `json`. Two shapes of the same table exist in
11
+ * the wild and nothing detected which one you had; this migration ends that.
12
+ *
13
+ * mysql2 parses a json column on the way out, so the read path receives the
14
+ * payload as a live object graph and rebuilds the session `Map` from it directly
15
+ * (`decodeSessionData`). The write path is unchanged - `encodeSessionData` still
16
+ * produces JSON text, which a json column stores verbatim.
17
+ *
18
+ * Everything below is a guard. Read them in order.
19
+ *
20
+ * 1. Table missing: nothing to converge
21
+ * ---------------------------------------
22
+ * It normally IS there - the create migration carries an earlier timestamp and
23
+ * runs first in the same batch - but a connection that hosts only part of the
24
+ * schema must not blow up here.
25
+ *
26
+ * 2. Column state probe: skip unless it is text-family
27
+ * ------------------------------------------------------
28
+ * The previous version of this migration was unconditional, on the argument that
29
+ * `MODIFY` to a type a column already has is a harmless rewrite. True on MySQL,
30
+ * and irrelevant everywhere else: it reached the schema builder's `alterTable()`,
31
+ * which resolves `AlterTableQueryCompiler` - and `orm-mssql` registers no
32
+ * implementation for it, so DI hands back the ABSTRACT class, whose `compile()`
33
+ * does not exist. That throw is recorded as a FAILED migration, and
34
+ * `assertNoFailed()` then refuses to run ANY migration on that connection ever
35
+ * again: the application never boots without manual surgery on the tracking
36
+ * table. Probing the target state first and returning early is the same shape
37
+ * `@spinajs/rbac`'s `RBACRegisteredAt_2026_07_28_00_00_00` already uses, and it
38
+ * makes the no-op case genuinely free rather than merely survivable.
39
+ *
40
+ * An unreadable probe skips too - see `columnNativeType`.
41
+ *
42
+ * 3. Dialect gate: MySQL only
43
+ * ------------------------------
44
+ * `MODIFY` and the `JSON` type are MySQL's. A text-family `Data` on MSSQL
45
+ * (`nvarchar`) or sqlite (`TEXT`) passes guard 2 and would then be handed
46
+ * syntax its server rejects - the same failed-migration outage guard 2 exists to
47
+ * prevent. Those dialects keep a text column and the read path keeps decoding a
48
+ * string, which is exactly what `decodeSessionData` does with it.
49
+ *
50
+ * 4. The wipe
51
+ * -----------
52
+ * Reached only when an actual `text -> json` conversion is about to happen.
53
+ * MySQL validates EVERY existing row during that conversion, and a single
54
+ * malformed / truncated / empty payload (a row from a crashed write, a row
55
+ * written by an older codec, a row truncated by TEXT's 64 KiB limit) fails the
56
+ * statement:
57
+ *
58
+ * ERROR 3140 (22032): Invalid JSON text: "Invalid value." at position 1
59
+ *
60
+ * Emptying the table first makes the conversion unconditionally safe. Sessions
61
+ * are disposable state: the worst a user sees is one forced re-login, and that
62
+ * is now paid ONLY by the deployments actually being converted - a fresh install
63
+ * skips at guard 2 and never deletes anything.
64
+ *
65
+ * `DELETE`, not `TRUNCATE`: truncate is not transactional, is refused outright
66
+ * by some engines for a table involved in foreign keys, and there is no volume
67
+ * here to make the difference worth having.
68
+ *
69
+ * 5. ONE statement, not three
70
+ * ----------------------------
71
+ * `alterTable()` compiles one `ICompilerOutput` per modified column and
72
+ * `SqlDriver.execute` wraps the array in `Promise.all` - three concurrent
73
+ * `ALTER TABLE`s on three pooled connections against one table. A partial
74
+ * failure leaves the table half-converted AND the migration marked failed. The
75
+ * raw escape hatch (`schema().raw`, compiled by `SqlRawSchemaQueryCompiler`,
76
+ * registered by every SQL driver via `orm-sql`) sends exactly one statement.
77
+ * The `CreatedAt`/`Expiration` widening that used to ride along here now lives
78
+ * in its own migration (`UserSessionTimestamps_2026_07_31_00_00_01`), because it
79
+ * is a cast that cannot fail and must stay independently applicable.
80
+ */
81
+ export declare class UserSessionDataJson_2026_07_31_00_00_00 extends OrmMigration {
82
+ up(connection: OrmDriver): Promise<void>;
83
+ /**
84
+ * Restores the text column. The sessions `up()` deleted are gone for good -
85
+ * that part is not reversible and nothing pretends otherwise - but the SHAPE
86
+ * is, and a package rollback that leaves a `json` column behind for a
87
+ * `2.0.488` reader is its own outage.
88
+ *
89
+ * Guarded by the inverse probe: only a column that is currently `json` is
90
+ * touched, so running `down()` twice, or against a database this migration
91
+ * never converted, does nothing.
92
+ *
93
+ * `TEXT` because `TEXT` is what the deployed databases had. Note this is a
94
+ * NARROWING cast - a stored payload above TEXT's 64 KiB limit would fail the
95
+ * statement in strict mode. That is acceptable here in a way it would not be
96
+ * in `up()`: `down()` runs only on an explicit, interactive rollback, never at
97
+ * boot, so a failure is loud and immediate rather than an unbootable service.
98
+ */
99
+ down(connection: OrmDriver): Promise<void>;
100
+ }
101
+ //# sourceMappingURL=UserSessionDataJson_2026_07_31_00_00_00.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserSessionDataJson_2026_07_31_00_00_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/UserSessionDataJson_2026_07_31_00_00_00.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,qBACa,uCAAwC,SAAQ,YAAY;IAC1D,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BrD;;;;;;;;;;;;;;;OAeG;IACU,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAaxD"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.UserSessionDataJson_2026_07_31_00_00_00 = void 0;
10
+ const orm_1 = require("@spinajs/orm");
11
+ const migration_support_js_1 = require("../migration-support.js");
12
+ /**
13
+ * Converts an EXISTING text-typed `user_sessions.Data` to a native MySQL `json`
14
+ * column, so the read path receives a parsed object graph instead of text.
15
+ *
16
+ * Databases created before the create-path migration
17
+ * (`UserSessionDBSqlMigration_2022_06_28_01_20_00`) declared `json` - i.e. every
18
+ * deployment - carry `Data text NOT NULL`. The create migration returns early
19
+ * when the table is already there, so the type it declares has never reached
20
+ * them. Fresh installs already get `json`. Two shapes of the same table exist in
21
+ * the wild and nothing detected which one you had; this migration ends that.
22
+ *
23
+ * mysql2 parses a json column on the way out, so the read path receives the
24
+ * payload as a live object graph and rebuilds the session `Map` from it directly
25
+ * (`decodeSessionData`). The write path is unchanged - `encodeSessionData` still
26
+ * produces JSON text, which a json column stores verbatim.
27
+ *
28
+ * Everything below is a guard. Read them in order.
29
+ *
30
+ * 1. Table missing: nothing to converge
31
+ * ---------------------------------------
32
+ * It normally IS there - the create migration carries an earlier timestamp and
33
+ * runs first in the same batch - but a connection that hosts only part of the
34
+ * schema must not blow up here.
35
+ *
36
+ * 2. Column state probe: skip unless it is text-family
37
+ * ------------------------------------------------------
38
+ * The previous version of this migration was unconditional, on the argument that
39
+ * `MODIFY` to a type a column already has is a harmless rewrite. True on MySQL,
40
+ * and irrelevant everywhere else: it reached the schema builder's `alterTable()`,
41
+ * which resolves `AlterTableQueryCompiler` - and `orm-mssql` registers no
42
+ * implementation for it, so DI hands back the ABSTRACT class, whose `compile()`
43
+ * does not exist. That throw is recorded as a FAILED migration, and
44
+ * `assertNoFailed()` then refuses to run ANY migration on that connection ever
45
+ * again: the application never boots without manual surgery on the tracking
46
+ * table. Probing the target state first and returning early is the same shape
47
+ * `@spinajs/rbac`'s `RBACRegisteredAt_2026_07_28_00_00_00` already uses, and it
48
+ * makes the no-op case genuinely free rather than merely survivable.
49
+ *
50
+ * An unreadable probe skips too - see `columnNativeType`.
51
+ *
52
+ * 3. Dialect gate: MySQL only
53
+ * ------------------------------
54
+ * `MODIFY` and the `JSON` type are MySQL's. A text-family `Data` on MSSQL
55
+ * (`nvarchar`) or sqlite (`TEXT`) passes guard 2 and would then be handed
56
+ * syntax its server rejects - the same failed-migration outage guard 2 exists to
57
+ * prevent. Those dialects keep a text column and the read path keeps decoding a
58
+ * string, which is exactly what `decodeSessionData` does with it.
59
+ *
60
+ * 4. The wipe
61
+ * -----------
62
+ * Reached only when an actual `text -> json` conversion is about to happen.
63
+ * MySQL validates EVERY existing row during that conversion, and a single
64
+ * malformed / truncated / empty payload (a row from a crashed write, a row
65
+ * written by an older codec, a row truncated by TEXT's 64 KiB limit) fails the
66
+ * statement:
67
+ *
68
+ * ERROR 3140 (22032): Invalid JSON text: "Invalid value." at position 1
69
+ *
70
+ * Emptying the table first makes the conversion unconditionally safe. Sessions
71
+ * are disposable state: the worst a user sees is one forced re-login, and that
72
+ * is now paid ONLY by the deployments actually being converted - a fresh install
73
+ * skips at guard 2 and never deletes anything.
74
+ *
75
+ * `DELETE`, not `TRUNCATE`: truncate is not transactional, is refused outright
76
+ * by some engines for a table involved in foreign keys, and there is no volume
77
+ * here to make the difference worth having.
78
+ *
79
+ * 5. ONE statement, not three
80
+ * ----------------------------
81
+ * `alterTable()` compiles one `ICompilerOutput` per modified column and
82
+ * `SqlDriver.execute` wraps the array in `Promise.all` - three concurrent
83
+ * `ALTER TABLE`s on three pooled connections against one table. A partial
84
+ * failure leaves the table half-converted AND the migration marked failed. The
85
+ * raw escape hatch (`schema().raw`, compiled by `SqlRawSchemaQueryCompiler`,
86
+ * registered by every SQL driver via `orm-sql`) sends exactly one statement.
87
+ * The `CreatedAt`/`Expiration` widening that used to ride along here now lives
88
+ * in its own migration (`UserSessionTimestamps_2026_07_31_00_00_01`), because it
89
+ * is a cast that cannot fail and must stay independently applicable.
90
+ */
91
+ let UserSessionDataJson_2026_07_31_00_00_00 = class UserSessionDataJson_2026_07_31_00_00_00 extends orm_1.OrmMigration {
92
+ async up(connection) {
93
+ if (!(await connection.schema().tableExists('user_sessions'))) {
94
+ return;
95
+ }
96
+ const dataType = await (0, migration_support_js_1.columnNativeType)(connection, 'user_sessions', 'Data');
97
+ // already `json` (fresh install / already converged), unreadable, or a type
98
+ // nobody anticipated - all three mean "leave it alone"
99
+ if (dataType === null || !(0, migration_support_js_1.isTextFamily)(dataType)) {
100
+ return;
101
+ }
102
+ if (!(0, migration_support_js_1.isMySqlDialect)(connection)) {
103
+ return;
104
+ }
105
+ await connection.schema().raw('DELETE FROM user_sessions');
106
+ // Identifiers are backtick-quoted: this statement is MySQL-only by
107
+ // construction (guard 3), so portability of the quoting style is not a
108
+ // constraint, and quoting removes any question about `Data` being a MySQL
109
+ // keyword. `NOT NULL` is restated because MODIFY replaces the WHOLE column
110
+ // definition - omitting it would silently make the column nullable.
111
+ await connection.schema().raw('ALTER TABLE `user_sessions` MODIFY `Data` JSON NOT NULL');
112
+ }
113
+ /**
114
+ * Restores the text column. The sessions `up()` deleted are gone for good -
115
+ * that part is not reversible and nothing pretends otherwise - but the SHAPE
116
+ * is, and a package rollback that leaves a `json` column behind for a
117
+ * `2.0.488` reader is its own outage.
118
+ *
119
+ * Guarded by the inverse probe: only a column that is currently `json` is
120
+ * touched, so running `down()` twice, or against a database this migration
121
+ * never converted, does nothing.
122
+ *
123
+ * `TEXT` because `TEXT` is what the deployed databases had. Note this is a
124
+ * NARROWING cast - a stored payload above TEXT's 64 KiB limit would fail the
125
+ * statement in strict mode. That is acceptable here in a way it would not be
126
+ * in `up()`: `down()` runs only on an explicit, interactive rollback, never at
127
+ * boot, so a failure is loud and immediate rather than an unbootable service.
128
+ */
129
+ async down(connection) {
130
+ if (!(await connection.schema().tableExists('user_sessions'))) {
131
+ return;
132
+ }
133
+ const dataType = await (0, migration_support_js_1.columnNativeType)(connection, 'user_sessions', 'Data');
134
+ if (dataType !== 'json' || !(0, migration_support_js_1.isMySqlDialect)(connection)) {
135
+ return;
136
+ }
137
+ await connection.schema().raw('ALTER TABLE `user_sessions` MODIFY `Data` TEXT NOT NULL');
138
+ }
139
+ };
140
+ exports.UserSessionDataJson_2026_07_31_00_00_00 = UserSessionDataJson_2026_07_31_00_00_00;
141
+ exports.UserSessionDataJson_2026_07_31_00_00_00 = UserSessionDataJson_2026_07_31_00_00_00 = __decorate([
142
+ (0, orm_1.Migration)('session-provider-connection')
143
+ ], UserSessionDataJson_2026_07_31_00_00_00);
144
+ //# sourceMappingURL=UserSessionDataJson_2026_07_31_00_00_00.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserSessionDataJson_2026_07_31_00_00_00.js","sourceRoot":"","sources":["../../../src/migrations/UserSessionDataJson_2026_07_31_00_00_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sCAAkE;AAClE,kEAAyF;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AAEI,IAAM,uCAAuC,GAA7C,MAAM,uCAAwC,SAAQ,kBAAY;IAChE,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,uCAAgB,EAAC,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QAE7E,4EAA4E;QAC5E,uDAAuD;QACvD,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,IAAA,mCAAY,EAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAA,qCAAc,EAAC,UAAU,CAAC,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QAE3D,mEAAmE;QACnE,uEAAuE;QACvE,0EAA0E;QAC1E,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IAC3F,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,KAAK,CAAC,IAAI,CAAC,UAAqB;QACrC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,uCAAgB,EAAC,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QAE7E,IAAI,QAAQ,KAAK,MAAM,IAAI,CAAC,IAAA,qCAAc,EAAC,UAAU,CAAC,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IAC3F,CAAC;CACF,CAAA;AAzDY,0FAAuC;kDAAvC,uCAAuC;IADnD,IAAA,eAAS,EAAC,6BAA6B,CAAC;GAC5B,uCAAuC,CAyDnD"}
@@ -0,0 +1,68 @@
1
+ import { OrmMigration, OrmDriver } from '@spinajs/orm';
2
+ /**
3
+ * Widens `user_sessions.CreatedAt` / `Expiration` from `date` to `datetime`.
4
+ *
5
+ * !! This is a correctness fix in its own right and has nothing to do with the
6
+ * JSON conversion it used to be bundled with. It is a separate migration
7
+ * precisely so it can be applied, skipped, reviewed and reverted on its own.
8
+ *
9
+ * The bug
10
+ * -------
11
+ * A MySQL `date` column stores only the calendar day - MySQL truncates the time
12
+ * component on write, silently:
13
+ *
14
+ * INSERT INTO probe VALUES ('2026-07-31 23:45:12', '2026-07-31 23:45:12');
15
+ * asDate asDateTime
16
+ * 2026-07-31 2026-07-31 23:45:12
17
+ *
18
+ * So on a deployed database a session's `Expiration` has no time of day: a
19
+ * session created at 23:45 with a 60-minute sliding TTL, due to expire at
20
+ * 00:45:12, is stored as expiring at 00:00:00 and the cleanup sweep kills it
21
+ * ~45 minutes early. Sliding expiration, `SessionProvider.isExpired`,
22
+ * `cleanupExpired` and `touch` all operate on that truncated value. `DbSession`
23
+ * declares both fields as luxon `DateTime` and the create path has declared both
24
+ * as `dateTime` since 2024; `datetime` is the type the code has always assumed
25
+ * it had.
26
+ *
27
+ * Why this one is safe where the JSON one was not
28
+ * -----------------------------------------------
29
+ * `date -> datetime` is a WIDENING cast. Every existing value is representable
30
+ * in the target type (midnight of the stored day), so unlike the `text -> json`
31
+ * conversion it cannot fail on row content and needs no wipe. Nothing is
32
+ * deleted here.
33
+ *
34
+ * Guards mirror the JSON migration: skip when the table is absent, skip unless
35
+ * `CreatedAt` is currently exactly `date`, skip on any non-MySQL dialect
36
+ * (`MODIFY` is MySQL syntax; a failed migration at boot bricks every later
37
+ * migration on the connection through `assertNoFailed()`). `CreatedAt` alone is
38
+ * probed - the two columns were created by the same statement in every database
39
+ * that has the old shape, and a `date`/`datetime` split between them has never
40
+ * existed.
41
+ *
42
+ * ONE statement with two `MODIFY` clauses, via the raw escape hatch, rather than
43
+ * `alterTable()`: the builder compiles one statement per column and
44
+ * `SqlDriver.execute` runs them through `Promise.all`, i.e. two concurrent
45
+ * `ALTER TABLE`s on the same table from two pooled connections.
46
+ *
47
+ * Nullability is restated verbatim from the create path - `MODIFY` replaces the
48
+ * whole column definition, and `CreatedAt` is `notNull()` there while
49
+ * `Expiration` is nullable (a never-expiring session persists a NULL).
50
+ */
51
+ export declare class UserSessionTimestamps_2026_07_31_00_00_01 extends OrmMigration {
52
+ up(connection: OrmDriver): Promise<void>;
53
+ /**
54
+ * Deliberately a no-op, and this is a decision rather than an omission.
55
+ *
56
+ * `up()` widened `date -> datetime`. Reversing it would be a NARROWING cast
57
+ * that silently truncates the time-of-day off every stored row - it destroys
58
+ * data, and it re-introduces the exact expiry bug this migration exists to
59
+ * fix, on a schema whose model and create path have declared `dateTime` for
60
+ * years. A `datetime` column is also perfectly readable by every version of
61
+ * this package, so a rollback has nothing to gain from shrinking it.
62
+ *
63
+ * (The JSON migration's `down()` is implemented, because there the old readers
64
+ * genuinely cannot cope with the new column type. That is not the case here.)
65
+ */
66
+ down(_connection: OrmDriver): Promise<void>;
67
+ }
68
+ //# sourceMappingURL=UserSessionTimestamps_2026_07_31_00_00_01.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserSessionTimestamps_2026_07_31_00_00_01.d.ts","sourceRoot":"","sources":["../../../src/migrations/UserSessionTimestamps_2026_07_31_00_00_01.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBACa,yCAA0C,SAAQ,YAAY;IAC5D,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrD;;;;;;;;;;;;OAYG;IAEU,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CACzD"}