@storyshelf/db-mysql 0.6.2 → 0.7.0

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 (92) hide show
  1. package/README.md +36 -0
  2. package/dist/ddl.d.mts +1 -1
  3. package/dist/ddl.mjs +381 -138
  4. package/dist/ddl.mjs.map +1 -1
  5. package/dist/drizzle-factory-mysql.mjs +7 -1
  6. package/dist/drizzle-factory-mysql.mjs.map +1 -1
  7. package/dist/foreign-keys.mjs +339 -0
  8. package/dist/foreign-keys.mjs.map +1 -0
  9. package/dist/index.mjs +10 -5
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/migrate.mjs +300 -72
  12. package/dist/migrate.mjs.map +1 -1
  13. package/dist/schema/baseline.d.mts +60 -6
  14. package/dist/schema/baseline.mjs +6 -2
  15. package/dist/schema/baseline.mjs.map +1 -1
  16. package/dist/schema/{status-config.d.mts → build-component.d.mts} +46 -39
  17. package/dist/schema/build-component.mjs +26 -0
  18. package/dist/schema/build-component.mjs.map +1 -0
  19. package/dist/schema/build-review.d.mts +118 -0
  20. package/dist/schema/build-review.mjs +24 -0
  21. package/dist/schema/build-review.mjs.map +1 -0
  22. package/dist/schema/build.d.mts +44 -8
  23. package/dist/schema/build.mjs +5 -1
  24. package/dist/schema/build.mjs.map +1 -1
  25. package/dist/schema/capture-attempt.d.mts +18 -18
  26. package/dist/schema/capture-attempt.mjs +2 -1
  27. package/dist/schema/capture-attempt.mjs.map +1 -1
  28. package/dist/schema/capture-job.d.mts +330 -0
  29. package/dist/schema/capture-job.mjs +57 -0
  30. package/dist/schema/capture-job.mjs.map +1 -0
  31. package/dist/schema/capture-shard.d.mts +257 -0
  32. package/dist/schema/capture-shard.mjs +41 -0
  33. package/dist/schema/capture-shard.mjs.map +1 -0
  34. package/dist/schema/comment.d.mts +24 -6
  35. package/dist/schema/comment.mjs +5 -3
  36. package/dist/schema/comment.mjs.map +1 -1
  37. package/dist/schema/connection.d.mts +173 -0
  38. package/dist/schema/connection.mjs +36 -0
  39. package/dist/schema/connection.mjs.map +1 -0
  40. package/dist/schema/content-refs.d.mts +6 -6
  41. package/dist/schema/content-refs.mjs +2 -1
  42. package/dist/schema/content-refs.mjs.map +1 -1
  43. package/dist/schema/datetime.mjs +47 -0
  44. package/dist/schema/datetime.mjs.map +1 -0
  45. package/dist/schema/design.d.mts +589 -0
  46. package/dist/schema/design.mjs +74 -0
  47. package/dist/schema/design.mjs.map +1 -0
  48. package/dist/schema/insight.d.mts +633 -0
  49. package/dist/schema/insight.mjs +69 -0
  50. package/dist/schema/insight.mjs.map +1 -0
  51. package/dist/schema/label.d.mts +6 -6
  52. package/dist/schema/label.mjs +2 -1
  53. package/dist/schema/label.mjs.map +1 -1
  54. package/dist/schema/member.d.mts +3 -3
  55. package/dist/schema/member.mjs +2 -1
  56. package/dist/schema/member.mjs.map +1 -1
  57. package/dist/schema/notification.d.mts +45 -9
  58. package/dist/schema/notification.mjs +7 -1
  59. package/dist/schema/notification.mjs.map +1 -1
  60. package/dist/schema/project-group-mapping.d.mts +3 -3
  61. package/dist/schema/project-group-mapping.mjs +2 -1
  62. package/dist/schema/project-group-mapping.mjs.map +1 -1
  63. package/dist/schema/project.d.mts +132 -6
  64. package/dist/schema/project.mjs +10 -2
  65. package/dist/schema/project.mjs.map +1 -1
  66. package/dist/schema/site-setting.d.mts +99 -0
  67. package/dist/schema/site-setting.mjs +24 -0
  68. package/dist/schema/site-setting.mjs.map +1 -0
  69. package/dist/schema/snapshot.d.mts +117 -9
  70. package/dist/schema/snapshot.mjs +13 -2
  71. package/dist/schema/snapshot.mjs.map +1 -1
  72. package/dist/schema/token.d.mts +6 -6
  73. package/dist/schema/token.mjs +2 -1
  74. package/dist/schema/token.mjs.map +1 -1
  75. package/dist/schema/usage.d.mts +267 -0
  76. package/dist/schema/usage.mjs +37 -0
  77. package/dist/schema/usage.mjs.map +1 -0
  78. package/dist/schema/user-invite.d.mts +9 -9
  79. package/dist/schema/user-invite.mjs +2 -1
  80. package/dist/schema/user-invite.mjs.map +1 -1
  81. package/dist/schema/user.d.mts +6 -6
  82. package/dist/schema/user.mjs +2 -1
  83. package/dist/schema/user.mjs.map +1 -1
  84. package/dist/schema/webhook.d.mts +6 -6
  85. package/dist/schema/webhook.mjs +2 -1
  86. package/dist/schema/webhook.mjs.map +1 -1
  87. package/dist/schema.d.mts +24 -3
  88. package/dist/schema.mjs +25 -4
  89. package/dist/schema.mjs.map +1 -1
  90. package/package.json +5 -5
  91. package/dist/schema/status-config.mjs +0 -26
  92. package/dist/schema/status-config.mjs.map +0 -1
@@ -145,10 +145,10 @@ declare const comments: import("drizzle-orm/mysql-core").MySqlTableWithColumns<{
145
145
  createdAt: import("drizzle-orm/mysql-core").MySqlColumn<{
146
146
  name: "created_at";
147
147
  tableName: "comments";
148
- dataType: "string";
149
- columnType: "MySqlDateTimeString";
148
+ dataType: "custom";
149
+ columnType: "MySqlCustomColumn";
150
150
  data: string;
151
- driverParam: string | number;
151
+ driverParam: string;
152
152
  notNull: true;
153
153
  hasDefault: false;
154
154
  isPrimaryKey: false;
@@ -162,10 +162,10 @@ declare const comments: import("drizzle-orm/mysql-core").MySqlTableWithColumns<{
162
162
  updatedAt: import("drizzle-orm/mysql-core").MySqlColumn<{
163
163
  name: "updated_at";
164
164
  tableName: "comments";
165
- dataType: "string";
166
- columnType: "MySqlDateTimeString";
165
+ dataType: "custom";
166
+ columnType: "MySqlCustomColumn";
167
167
  data: string;
168
- driverParam: string | number;
168
+ driverParam: string;
169
169
  notNull: true;
170
170
  hasDefault: false;
171
171
  isPrimaryKey: false;
@@ -176,6 +176,23 @@ declare const comments: import("drizzle-orm/mysql-core").MySqlTableWithColumns<{
176
176
  identity: undefined;
177
177
  generated: undefined;
178
178
  }, {}, {}>;
179
+ storyId: import("drizzle-orm/mysql-core").MySqlColumn<{
180
+ name: "story_id";
181
+ tableName: "comments";
182
+ dataType: "string";
183
+ columnType: "MySqlText";
184
+ data: string;
185
+ driverParam: string;
186
+ notNull: false;
187
+ hasDefault: false;
188
+ isPrimaryKey: false;
189
+ isAutoincrement: false;
190
+ hasRuntimeDefault: false;
191
+ enumValues: [string, ...string[]];
192
+ baseColumn: never;
193
+ identity: undefined;
194
+ generated: undefined;
195
+ }, {}, {}>;
179
196
  };
180
197
  dialect: 'mysql';
181
198
  }>;
@@ -191,6 +208,7 @@ interface Comment {
191
208
  resolved: boolean;
192
209
  createdAt: string;
193
210
  updatedAt: string;
211
+ storyId: string | null;
194
212
  }
195
213
  //#endregion
196
214
  export { Comment, comments };
@@ -1,11 +1,12 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { datetime } from "./datetime.mjs";
4
5
  import { projects } from "./project.mjs";
5
6
  import { builds } from "./build.mjs";
6
- import { snapshots } from "./snapshot.mjs";
7
7
  import { users } from "./user.mjs";
8
- import { boolean, datetime, index, mysqlTable, text } from "drizzle-orm/mysql-core";
8
+ import { snapshots } from "./snapshot.mjs";
9
+ import { boolean, index, mysqlTable, text } from "drizzle-orm/mysql-core";
9
10
  //#region src/schema/comment.ts
10
11
  /** Narrow `comments` table definition. */
11
12
  const comments = mysqlTable("comments", {
@@ -24,7 +25,8 @@ const comments = mysqlTable("comments", {
24
25
  updatedAt: datetime("updated_at", {
25
26
  mode: "string",
26
27
  fsp: 3
27
- }).notNull()
28
+ }).notNull(),
29
+ storyId: text("story_id")
28
30
  }, (t) => [index("comments_build_id_idx").on(t.buildId)]);
29
31
  //#endregion
30
32
  export { comments };
@@ -1 +1 @@
1
- {"version":3,"file":"comment.mjs","names":[],"sources":["../../src/schema/comment.ts"],"sourcesContent":["import { boolean, index, mysqlTable, text, datetime } from \"drizzle-orm/mysql-core\";\nimport { builds } from \"./build.ts\";\nimport { projects } from \"./project.ts\";\nimport { snapshots } from \"./snapshot.ts\";\nimport { users } from \"./user.ts\";\n\n/** Narrow `comments` table definition. */\nexport const comments = mysqlTable(\n \"comments\",\n {\n id: text(\"id\").primaryKey(),\n projectId: text(\"project_id\")\n .notNull()\n .references(() => projects.id, { onDelete: \"cascade\" }),\n buildId: text(\"build_id\")\n .notNull()\n .references(() => builds.id, { onDelete: \"cascade\" }),\n snapshotId: text(\"snapshot_id\").references(() => snapshots.id, { onDelete: \"cascade\" }),\n userId: text(\"user_id\").references(() => users.id, { onDelete: \"cascade\" }),\n body: text(\"body\").notNull(),\n parentId: text(\"parent_id\"),\n resolved: boolean(\"resolved\").notNull().default(false),\n createdAt: datetime(\"created_at\", { mode: \"string\", fsp: 3 }).notNull(),\n updatedAt: datetime(\"updated_at\", { mode: \"string\", fsp: 3 }).notNull(),\n },\n (t) => [index(\"comments_build_id_idx\").on(t.buildId)],\n);\n\n/** A comment row. */\nexport interface Comment {\n id: string;\n projectId: string;\n buildId: string;\n snapshotId: string | null;\n userId: string | null;\n body: string;\n parentId: string | null;\n resolved: boolean;\n createdAt: string;\n updatedAt: string;\n}\n"],"mappings":";;;;;;;;;;AAOA,MAAa,WAAW,WACtB,YACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,WAAW,KAAK,YAAY,CAAC,CAC1B,QAAQ,CAAC,CACT,iBAAiB,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;CACxD,SAAS,KAAK,UAAU,CAAC,CACtB,QAAQ,CAAC,CACT,iBAAiB,OAAO,IAAI,EAAE,UAAU,UAAU,CAAC;CACtD,YAAY,KAAK,aAAa,CAAC,CAAC,iBAAiB,UAAU,IAAI,EAAE,UAAU,UAAU,CAAC;CACtF,QAAQ,KAAK,SAAS,CAAC,CAAC,iBAAiB,MAAM,IAAI,EAAE,UAAU,UAAU,CAAC;CAC1E,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,UAAU,KAAK,WAAW;CAC1B,UAAU,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACrD,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACtE,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;AACxE,IACC,MAAM,CAAC,MAAM,uBAAuB,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CACtD"}
1
+ {"version":3,"file":"comment.mjs","names":[],"sources":["../../src/schema/comment.ts"],"sourcesContent":["import { boolean, index, mysqlTable, text } from \"drizzle-orm/mysql-core\";\nimport { builds } from \"./build.ts\";\nimport { datetime } from \"./datetime.ts\";\nimport { projects } from \"./project.ts\";\nimport { snapshots } from \"./snapshot.ts\";\nimport { users } from \"./user.ts\";\n\n/** Narrow `comments` table definition. */\nexport const comments = mysqlTable(\n \"comments\",\n {\n id: text(\"id\").primaryKey(),\n projectId: text(\"project_id\")\n .notNull()\n .references(() => projects.id, { onDelete: \"cascade\" }),\n buildId: text(\"build_id\")\n .notNull()\n .references(() => builds.id, { onDelete: \"cascade\" }),\n snapshotId: text(\"snapshot_id\").references(() => snapshots.id, { onDelete: \"cascade\" }),\n userId: text(\"user_id\").references(() => users.id, { onDelete: \"cascade\" }),\n body: text(\"body\").notNull(),\n parentId: text(\"parent_id\"),\n resolved: boolean(\"resolved\").notNull().default(false),\n createdAt: datetime(\"created_at\", { mode: \"string\", fsp: 3 }).notNull(),\n updatedAt: datetime(\"updated_at\", { mode: \"string\", fsp: 3 }).notNull(),\n storyId: text(\"story_id\"),\n },\n (t) => [index(\"comments_build_id_idx\").on(t.buildId)],\n);\n\n/** A comment row. */\nexport interface Comment {\n id: string;\n projectId: string;\n buildId: string;\n snapshotId: string | null;\n userId: string | null;\n body: string;\n parentId: string | null;\n resolved: boolean;\n createdAt: string;\n updatedAt: string;\n storyId: string | null;\n}\n"],"mappings":";;;;;;;;;;;AAQA,MAAa,WAAW,WACtB,YACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,WAAW,KAAK,YAAY,CAAC,CAC1B,QAAQ,CAAC,CACT,iBAAiB,SAAS,IAAI,EAAE,UAAU,UAAU,CAAC;CACxD,SAAS,KAAK,UAAU,CAAC,CACtB,QAAQ,CAAC,CACT,iBAAiB,OAAO,IAAI,EAAE,UAAU,UAAU,CAAC;CACtD,YAAY,KAAK,aAAa,CAAC,CAAC,iBAAiB,UAAU,IAAI,EAAE,UAAU,UAAU,CAAC;CACtF,QAAQ,KAAK,SAAS,CAAC,CAAC,iBAAiB,MAAM,IAAI,EAAE,UAAU,UAAU,CAAC;CAC1E,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,UAAU,KAAK,WAAW;CAC1B,UAAU,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,KAAK;CACrD,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACtE,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACtE,SAAS,KAAK,UAAU;AAC1B,IACC,MAAM,CAAC,MAAM,uBAAuB,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CACtD"}
@@ -0,0 +1,173 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ //#region src/schema/connection.d.ts
4
+ /**
5
+ * A user's own OAuth connection to an external service (Figma, later Jira/Linear/…),
6
+ * one per user and service. `tokenEncrypted` is the access token; the refresh token
7
+ * is encrypted too. `status` is `ok` or `expired` (needs reconnecting).
8
+ */
9
+ declare const userConnections: import("drizzle-orm/mysql-core").MySqlTableWithColumns<{
10
+ name: "user_connections";
11
+ schema: undefined;
12
+ columns: {
13
+ id: import("drizzle-orm/mysql-core").MySqlColumn<{
14
+ name: "id";
15
+ tableName: "user_connections";
16
+ dataType: "string";
17
+ columnType: "MySqlText";
18
+ data: string;
19
+ driverParam: string;
20
+ notNull: true;
21
+ hasDefault: false;
22
+ isPrimaryKey: true;
23
+ isAutoincrement: false;
24
+ hasRuntimeDefault: false;
25
+ enumValues: [string, ...string[]];
26
+ baseColumn: never;
27
+ identity: undefined;
28
+ generated: undefined;
29
+ }, {}, {}>;
30
+ userId: import("drizzle-orm/mysql-core").MySqlColumn<{
31
+ name: "user_id";
32
+ tableName: "user_connections";
33
+ dataType: "string";
34
+ columnType: "MySqlText";
35
+ data: string;
36
+ driverParam: string;
37
+ notNull: true;
38
+ hasDefault: false;
39
+ isPrimaryKey: false;
40
+ isAutoincrement: false;
41
+ hasRuntimeDefault: false;
42
+ enumValues: [string, ...string[]];
43
+ baseColumn: never;
44
+ identity: undefined;
45
+ generated: undefined;
46
+ }, {}, {}>;
47
+ service: import("drizzle-orm/mysql-core").MySqlColumn<{
48
+ name: "service";
49
+ tableName: "user_connections";
50
+ dataType: "string";
51
+ columnType: "MySqlText";
52
+ data: string;
53
+ driverParam: string;
54
+ notNull: true;
55
+ hasDefault: false;
56
+ isPrimaryKey: false;
57
+ isAutoincrement: false;
58
+ hasRuntimeDefault: false;
59
+ enumValues: [string, ...string[]];
60
+ baseColumn: never;
61
+ identity: undefined;
62
+ generated: undefined;
63
+ }, {}, {}>;
64
+ tokenEncrypted: import("drizzle-orm/mysql-core").MySqlColumn<{
65
+ name: "token_encrypted";
66
+ tableName: "user_connections";
67
+ dataType: "string";
68
+ columnType: "MySqlText";
69
+ data: string;
70
+ driverParam: string;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: [string, ...string[]];
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {}>;
81
+ refreshTokenEncrypted: import("drizzle-orm/mysql-core").MySqlColumn<{
82
+ name: "refresh_token_encrypted";
83
+ tableName: "user_connections";
84
+ dataType: "string";
85
+ columnType: "MySqlText";
86
+ data: string;
87
+ driverParam: string;
88
+ notNull: false;
89
+ hasDefault: false;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: [string, ...string[]];
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {}>;
98
+ expiresAt: import("drizzle-orm/mysql-core").MySqlColumn<{
99
+ name: "expires_at";
100
+ tableName: "user_connections";
101
+ dataType: "custom";
102
+ columnType: "MySqlCustomColumn";
103
+ data: string;
104
+ driverParam: string;
105
+ notNull: false;
106
+ hasDefault: false;
107
+ isPrimaryKey: false;
108
+ isAutoincrement: false;
109
+ hasRuntimeDefault: false;
110
+ enumValues: undefined;
111
+ baseColumn: never;
112
+ identity: undefined;
113
+ generated: undefined;
114
+ }, {}, {}>;
115
+ status: import("drizzle-orm/mysql-core").MySqlColumn<{
116
+ name: "status";
117
+ tableName: "user_connections";
118
+ dataType: "string";
119
+ columnType: "MySqlText";
120
+ data: string;
121
+ driverParam: string;
122
+ notNull: true;
123
+ hasDefault: true;
124
+ isPrimaryKey: false;
125
+ isAutoincrement: false;
126
+ hasRuntimeDefault: false;
127
+ enumValues: [string, ...string[]];
128
+ baseColumn: never;
129
+ identity: undefined;
130
+ generated: undefined;
131
+ }, {}, {}>;
132
+ createdAt: import("drizzle-orm/mysql-core").MySqlColumn<{
133
+ name: "created_at";
134
+ tableName: "user_connections";
135
+ dataType: "custom";
136
+ columnType: "MySqlCustomColumn";
137
+ data: string;
138
+ driverParam: string;
139
+ notNull: true;
140
+ hasDefault: false;
141
+ isPrimaryKey: false;
142
+ isAutoincrement: false;
143
+ hasRuntimeDefault: false;
144
+ enumValues: undefined;
145
+ baseColumn: never;
146
+ identity: undefined;
147
+ generated: undefined;
148
+ }, {}, {}>;
149
+ updatedAt: import("drizzle-orm/mysql-core").MySqlColumn<{
150
+ name: "updated_at";
151
+ tableName: "user_connections";
152
+ dataType: "custom";
153
+ columnType: "MySqlCustomColumn";
154
+ data: string;
155
+ driverParam: string;
156
+ notNull: true;
157
+ hasDefault: false;
158
+ isPrimaryKey: false;
159
+ isAutoincrement: false;
160
+ hasRuntimeDefault: false;
161
+ enumValues: undefined;
162
+ baseColumn: never;
163
+ identity: undefined;
164
+ generated: undefined;
165
+ }, {}, {}>;
166
+ };
167
+ dialect: 'mysql';
168
+ }>;
169
+ /** Row type of `user_connections`. */
170
+ type UserConnection = typeof userConnections.$inferSelect;
171
+ //#endregion
172
+ export { UserConnection, userConnections };
173
+ //# sourceMappingURL=connection.d.mts.map
@@ -0,0 +1,36 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { datetime } from "./datetime.mjs";
5
+ import { users } from "./user.mjs";
6
+ import { mysqlTable, text, uniqueIndex } from "drizzle-orm/mysql-core";
7
+ //#region src/schema/connection.ts
8
+ /**
9
+ * A user's own OAuth connection to an external service (Figma, later Jira/Linear/…),
10
+ * one per user and service. `tokenEncrypted` is the access token; the refresh token
11
+ * is encrypted too. `status` is `ok` or `expired` (needs reconnecting).
12
+ */
13
+ const userConnections = mysqlTable("user_connections", {
14
+ id: text("id").primaryKey(),
15
+ userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
16
+ service: text("service").notNull(),
17
+ tokenEncrypted: text("token_encrypted").notNull(),
18
+ refreshTokenEncrypted: text("refresh_token_encrypted"),
19
+ expiresAt: datetime("expires_at", {
20
+ mode: "string",
21
+ fsp: 3
22
+ }),
23
+ status: text("status").notNull().default("ok"),
24
+ createdAt: datetime("created_at", {
25
+ mode: "string",
26
+ fsp: 3
27
+ }).notNull(),
28
+ updatedAt: datetime("updated_at", {
29
+ mode: "string",
30
+ fsp: 3
31
+ }).notNull()
32
+ }, (t) => [uniqueIndex("user_connections_user_service_idx").on(t.userId, t.service)]);
33
+ //#endregion
34
+ export { userConnections };
35
+
36
+ //# sourceMappingURL=connection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.mjs","names":[],"sources":["../../src/schema/connection.ts"],"sourcesContent":["import { mysqlTable, text, uniqueIndex } from \"drizzle-orm/mysql-core\";\nimport { datetime } from \"./datetime.ts\";\nimport { users } from \"./user.ts\";\n\n/**\n * A user's own OAuth connection to an external service (Figma, later Jira/Linear/…),\n * one per user and service. `tokenEncrypted` is the access token; the refresh token\n * is encrypted too. `status` is `ok` or `expired` (needs reconnecting).\n */\nexport const userConnections = mysqlTable(\n \"user_connections\",\n {\n id: text(\"id\").primaryKey(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n service: text(\"service\").notNull(),\n tokenEncrypted: text(\"token_encrypted\").notNull(),\n refreshTokenEncrypted: text(\"refresh_token_encrypted\"),\n expiresAt: datetime(\"expires_at\", { mode: \"string\", fsp: 3 }),\n status: text(\"status\").notNull().default(\"ok\"),\n createdAt: datetime(\"created_at\", { mode: \"string\", fsp: 3 }).notNull(),\n updatedAt: datetime(\"updated_at\", { mode: \"string\", fsp: 3 }).notNull(),\n },\n (t) => [uniqueIndex(\"user_connections_user_service_idx\").on(t.userId, t.service)],\n);\n\n/** Row type of `user_connections`. */\nexport type UserConnection = typeof userConnections.$inferSelect;\n"],"mappings":";;;;;;;;;;;;AASA,MAAa,kBAAkB,WAC7B,oBACA;CACE,IAAI,KAAK,IAAI,CAAC,CAAC,WAAW;CAC1B,QAAQ,KAAK,SAAS,CAAC,CACpB,QAAQ,CAAC,CACT,iBAAiB,MAAM,IAAI,EAAE,UAAU,UAAU,CAAC;CACrD,SAAS,KAAK,SAAS,CAAC,CAAC,QAAQ;CACjC,gBAAgB,KAAK,iBAAiB,CAAC,CAAC,QAAQ;CAChD,uBAAuB,KAAK,yBAAyB;CACrD,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC;CAC5D,QAAQ,KAAK,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC7C,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACtE,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;AACxE,IACC,MAAM,CAAC,YAAY,mCAAmC,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAClF"}
@@ -43,10 +43,10 @@ declare const contentRefs: import("drizzle-orm/mysql-core").MySqlTableWithColumn
43
43
  lastSeenAt: import("drizzle-orm/mysql-core").MySqlColumn<{
44
44
  name: "last_seen_at";
45
45
  tableName: "content_refs";
46
- dataType: "string";
47
- columnType: "MySqlDateTimeString";
46
+ dataType: "custom";
47
+ columnType: "MySqlCustomColumn";
48
48
  data: string;
49
- driverParam: string | number;
49
+ driverParam: string;
50
50
  notNull: true;
51
51
  hasDefault: false;
52
52
  isPrimaryKey: false;
@@ -60,10 +60,10 @@ declare const contentRefs: import("drizzle-orm/mysql-core").MySqlTableWithColumn
60
60
  createdAt: import("drizzle-orm/mysql-core").MySqlColumn<{
61
61
  name: "created_at";
62
62
  tableName: "content_refs";
63
- dataType: "string";
64
- columnType: "MySqlDateTimeString";
63
+ dataType: "custom";
64
+ columnType: "MySqlCustomColumn";
65
65
  data: string;
66
- driverParam: string | number;
66
+ driverParam: string;
67
67
  notNull: true;
68
68
  hasDefault: false;
69
69
  isPrimaryKey: false;
@@ -1,7 +1,8 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- import { datetime, int, mysqlTable, text } from "drizzle-orm/mysql-core";
4
+ import { datetime } from "./datetime.mjs";
5
+ import { int, mysqlTable, text } from "drizzle-orm/mysql-core";
5
6
  //#region src/schema/content-refs.ts
6
7
  /** Content-addressed storage refs for deduplicated Storybook assets. */
7
8
  const contentRefs = mysqlTable("content_refs", {
@@ -1 +1 @@
1
- {"version":3,"file":"content-refs.mjs","names":[],"sources":["../../src/schema/content-refs.ts"],"sourcesContent":["import { int, mysqlTable, text, datetime } from \"drizzle-orm/mysql-core\";\n\n/** Content-addressed storage refs for deduplicated Storybook assets. */\nexport const contentRefs = mysqlTable(\"content_refs\", {\n hash: text(\"hash\").primaryKey(),\n refCount: int(\"ref_count\").notNull().default(1),\n lastSeenAt: datetime(\"last_seen_at\", { mode: \"string\", fsp: 3 }).notNull(),\n createdAt: datetime(\"created_at\", { mode: \"string\", fsp: 3 }).notNull(),\n});\n\n/** Content ref row. */\nexport interface ContentRef {\n hash: string;\n refCount: number;\n lastSeenAt: string;\n createdAt: string;\n}\n"],"mappings":";;;;;;AAGA,MAAa,cAAc,WAAW,gBAAgB;CACpD,MAAM,KAAK,MAAM,CAAC,CAAC,WAAW;CAC9B,UAAU,IAAI,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;CAC9C,YAAY,SAAS,gBAAgB;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACzE,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;AACxE,CAAC"}
1
+ {"version":3,"file":"content-refs.mjs","names":[],"sources":["../../src/schema/content-refs.ts"],"sourcesContent":["import { int, mysqlTable, text } from \"drizzle-orm/mysql-core\";\nimport { datetime } from \"./datetime.ts\";\n\n/** Content-addressed storage refs for deduplicated Storybook assets. */\nexport const contentRefs = mysqlTable(\"content_refs\", {\n hash: text(\"hash\").primaryKey(),\n refCount: int(\"ref_count\").notNull().default(1),\n lastSeenAt: datetime(\"last_seen_at\", { mode: \"string\", fsp: 3 }).notNull(),\n createdAt: datetime(\"created_at\", { mode: \"string\", fsp: 3 }).notNull(),\n});\n\n/** Content ref row. */\nexport interface ContentRef {\n hash: string;\n refCount: number;\n lastSeenAt: string;\n createdAt: string;\n}\n"],"mappings":";;;;;;;AAIA,MAAa,cAAc,WAAW,gBAAgB;CACpD,MAAM,KAAK,MAAM,CAAC,CAAC,WAAW;CAC9B,UAAU,IAAI,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;CAC9C,YAAY,SAAS,gBAAgB;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;CACzE,WAAW,SAAS,cAAc;EAAE,MAAM;EAAU,KAAK;CAAE,CAAC,CAAC,CAAC,QAAQ;AACxE,CAAC"}
@@ -0,0 +1,47 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { customType } from "drizzle-orm/mysql-core";
5
+ //#region src/schema/datetime.ts
6
+ /**
7
+ * MySQL DATETIME(3) column that keeps StoryShelf's ISO-8601 timestamps.
8
+ *
9
+ * MySQL does not accept `2026-10-24T10:34:17.691Z`; the adapter stores UTC
10
+ * values as `2026-10-24 10:34:17.691` and converts them back on read. Keeping
11
+ * the conversion on the column means inserts, updates and every comparison
12
+ * (queue leases, retention cut-offs) use the same form.
13
+ */
14
+ const datetime = customType({
15
+ dataType(config) {
16
+ return `datetime(${config?.fsp ?? 3})`;
17
+ },
18
+ toDriver(value) {
19
+ return toMySqlDateTime(value);
20
+ },
21
+ fromDriver(value) {
22
+ return fromMySqlDateTime(value);
23
+ }
24
+ });
25
+ function toMySqlDateTime(iso) {
26
+ const time = new Date(iso).getTime();
27
+ if (Number.isNaN(time)) return iso;
28
+ return new Date(time).toISOString().slice(0, 23).replace("T", " ");
29
+ }
30
+ function fromMySqlDateTime(value) {
31
+ if (value instanceof Date) return wallClockIso(value);
32
+ if (value.includes("T")) return value;
33
+ const [date, time] = value.split(" ");
34
+ if (!date || !time) return value;
35
+ const parsed = /* @__PURE__ */ new Date(`${date}T${time}Z`);
36
+ return Number.isNaN(parsed.getTime()) ? value : parsed.toISOString();
37
+ }
38
+ function wallClockIso(date) {
39
+ return `${`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`}T${`${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`}.${pad(date.getMilliseconds(), 3)}Z`;
40
+ }
41
+ function pad(value, width = 2) {
42
+ return String(value).padStart(width, "0");
43
+ }
44
+ //#endregion
45
+ export { datetime, fromMySqlDateTime, toMySqlDateTime };
46
+
47
+ //# sourceMappingURL=datetime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datetime.mjs","names":[],"sources":["../../src/schema/datetime.ts"],"sourcesContent":["/**\n * MySQL DATETIME(3) column that keeps StoryShelf's ISO-8601 timestamps.\n *\n * MySQL does not accept `2026-10-24T10:34:17.691Z`; the adapter stores UTC\n * values as `2026-10-24 10:34:17.691` and converts them back on read. Keeping\n * the conversion on the column means inserts, updates and every comparison\n * (queue leases, retention cut-offs) use the same form.\n */\nimport { customType } from \"drizzle-orm/mysql-core\";\n\ninterface DateTimeConfig {\n mode?: \"string\";\n fsp?: number;\n}\n\nexport const datetime = customType<{\n data: string;\n driverData: string;\n config: DateTimeConfig;\n}>({\n dataType(config) {\n return `datetime(${config?.fsp ?? 3})`;\n },\n toDriver(value: string): string {\n return toMySqlDateTime(value);\n },\n fromDriver(value: string): string {\n return fromMySqlDateTime(value);\n },\n});\n\nexport function toMySqlDateTime(iso: string): string {\n const time = new Date(iso).getTime();\n if (Number.isNaN(time)) {\n return iso;\n }\n return new Date(time).toISOString().slice(0, 23).replace(\"T\", \" \");\n}\n\nexport function fromMySqlDateTime(value: string | Date): string {\n if (value instanceof Date) {\n return wallClockIso(value);\n }\n if (value.includes(\"T\")) {\n return value;\n }\n const [date, time] = value.split(\" \");\n if (!date || !time) {\n return value;\n }\n const parsed = new Date(`${date}T${time}Z`);\n return Number.isNaN(parsed.getTime()) ? value : parsed.toISOString();\n}\n\nfunction wallClockIso(date: Date): string {\n const day = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n const time = `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;\n return `${day}T${time}.${pad(date.getMilliseconds(), 3)}Z`;\n}\n\nfunction pad(value: number, width = 2): string {\n return String(value).padStart(width, \"0\");\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAa,WAAW,WAIrB;CACD,SAAS,QAAQ;EACf,OAAO,YAAY,QAAQ,OAAO,EAAE;CACtC;CACA,SAAS,OAAuB;EAC9B,OAAO,gBAAgB,KAAK;CAC9B;CACA,WAAW,OAAuB;EAChC,OAAO,kBAAkB,KAAK;CAChC;AACF,CAAC;AAED,SAAgB,gBAAgB,KAAqB;CACnD,MAAM,OAAO,IAAI,KAAK,GAAG,CAAC,CAAC,QAAQ;CACnC,IAAI,OAAO,MAAM,IAAI,GACnB,OAAO;CAET,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ,KAAK,GAAG;AACnE;AAEA,SAAgB,kBAAkB,OAA8B;CAC9D,IAAI,iBAAiB,MACnB,OAAO,aAAa,KAAK;CAE3B,IAAI,MAAM,SAAS,GAAG,GACpB,OAAO;CAET,MAAM,CAAC,MAAM,QAAQ,MAAM,MAAM,GAAG;CACpC,IAAI,CAAC,QAAQ,CAAC,MACZ,OAAO;CAET,MAAM,yBAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE;CAC1C,OAAO,OAAO,MAAM,OAAO,QAAQ,CAAC,IAAI,QAAQ,OAAO,YAAY;AACrE;AAEA,SAAS,aAAa,MAAoB;CAGxC,OAAO,GAAG,GAFK,KAAK,YAAY,EAAE,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,EAAE,GAAG,IAAI,KAAK,QAAQ,CAAC,IAErE,GAAG,GADD,IAAI,KAAK,SAAS,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC,EAAE,GAAG,IAAI,KAAK,WAAW,CAAC,IACjE,GAAG,IAAI,KAAK,gBAAgB,GAAG,CAAC,EAAE;AAC1D;AAEA,SAAS,IAAI,OAAe,QAAQ,GAAW;CAC7C,OAAO,OAAO,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG;AAC1C"}