@remit/drizzle-sqlite-schema 0.0.34 → 0.0.36
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/dist/schema.d.ts +338 -387
- package/dist/schema.js +29 -30
- package/dist/types.d.ts +81 -1
- package/dist/types.js +136 -6
- package/package.json +1 -4
- package/schema.ts +36 -40
- package/types.ts +150 -6
package/dist/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { index, integer, primaryKey,
|
|
1
|
+
import { index, integer, primaryKey, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
2
2
|
import { generateBase36Id, nullableInteger, nullableText } from "./types.js";
|
|
3
3
|
export const accountExportRequests = sqliteTable("account_export_request", {
|
|
4
4
|
accountExportRequestId: text("account_export_request_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
@@ -41,6 +41,20 @@ export const quarantines = sqliteTable("quarantine", {
|
|
|
41
41
|
}, (table) => [
|
|
42
42
|
index("quarantine_by_account_config_id").on(table.accountConfigId, table.quarantinedAt),
|
|
43
43
|
]);
|
|
44
|
+
export const syncWarnings = sqliteTable("sync_warning", {
|
|
45
|
+
syncWarningId: text("sync_warning_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
46
|
+
accountConfigId: text("account_config_id").notNull(),
|
|
47
|
+
accountId: text("account_id").notNull(),
|
|
48
|
+
mailboxId: text("mailbox_id").notNull(),
|
|
49
|
+
uidValidity: integer("uid_validity", { mode: "number" }).notNull(),
|
|
50
|
+
uid: integer("uid", { mode: "number" }).notNull(),
|
|
51
|
+
stage: text("stage").$type().notNull(),
|
|
52
|
+
attempts: integer("attempts").notNull(),
|
|
53
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
54
|
+
}, (table) => [
|
|
55
|
+
index("sync_warning_by_mailbox_id").on(table.mailboxId),
|
|
56
|
+
index("sync_warning_by_account_config_id").on(table.accountConfigId, table.createdAt),
|
|
57
|
+
]);
|
|
44
58
|
export const accountConfigs = sqliteTable("account_config", {
|
|
45
59
|
accountConfigId: text("account_config_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
46
60
|
userId: text("user_id").notNull(),
|
|
@@ -128,11 +142,10 @@ export const filters = sqliteTable("filter", {
|
|
|
128
142
|
ttl: integer("ttl", { mode: "number" }),
|
|
129
143
|
state: text("state").$type().notNull().default("Active"),
|
|
130
144
|
disabledReason: text("disabled_reason").$type().notNull().default("None"),
|
|
131
|
-
hasAnchor: integer("has_anchor", { mode: "boolean" }).notNull().default(false),
|
|
132
145
|
ruleChangedAt: integer("rule_changed_at", { mode: "number" }).notNull(),
|
|
133
146
|
actionChangedAt: integer("action_changed_at", { mode: "number" }).notNull(),
|
|
134
147
|
matchOperator: text("match_operator").$type().notNull().default("And"),
|
|
135
|
-
literalClauses: text("literal_clauses", { mode: "json" }).notNull()
|
|
148
|
+
literalClauses: text("literal_clauses", { mode: "json" }).notNull(),
|
|
136
149
|
actionLabelId: text("action_label_id").notNull().default("None"),
|
|
137
150
|
actionMailboxId: text("action_mailbox_id").notNull().default("None"),
|
|
138
151
|
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
@@ -159,10 +172,8 @@ export const organizeJobRequests = sqliteTable("organize_job_request", {
|
|
|
159
172
|
userId: text("user_id").notNull(),
|
|
160
173
|
state: text("state").$type().notNull().default("Pending"),
|
|
161
174
|
filterId: text("filter_id").notNull().default("None"),
|
|
162
|
-
anchorMessageId: text("anchor_message_id").notNull().default("None"),
|
|
163
175
|
matchOperator: text("match_operator").$type().notNull().default("And"),
|
|
164
176
|
literalClauses: text("literal_clauses", { mode: "json" }).notNull().default([]),
|
|
165
|
-
similarityThreshold: real("similarity_threshold").notNull().default(0.75),
|
|
166
177
|
actionLabelId: text("action_label_id").notNull().default("None"),
|
|
167
178
|
actionMailboxId: text("action_mailbox_id").notNull().default("None"),
|
|
168
179
|
matchedCount: integer("matched_count").notNull().default(0),
|
|
@@ -320,15 +331,15 @@ export const addresses = sqliteTable("address", {
|
|
|
320
331
|
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
321
332
|
}, (table) => [
|
|
322
333
|
index("address_by_account_config_id").on(table.accountConfigId, table.normalizedCompound),
|
|
334
|
+
index("address_by_normalized_email").on(table.accountConfigId, table.normalizedEmail),
|
|
323
335
|
]);
|
|
324
|
-
export const
|
|
336
|
+
export const messageRecords = sqliteTable("message", {
|
|
325
337
|
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
326
338
|
mailboxId: text("mailbox_id").notNull(),
|
|
327
339
|
uid: integer("uid", { mode: "number" }).notNull(),
|
|
328
340
|
sequenceNumber: integer("sequence_number").notNull(),
|
|
329
341
|
rfc822Size: integer("rfc822_size", { mode: "number" }).notNull(),
|
|
330
342
|
internalDate: integer("internal_date", { mode: "number" }).notNull(),
|
|
331
|
-
messageIdHeader: nullableText("message_id_header"),
|
|
332
343
|
envelopeId: text("envelope_id").notNull(),
|
|
333
344
|
rootBodyPartId: text("root_body_part_id").notNull(),
|
|
334
345
|
bodyStorageKey: nullableText("body_storage_key"),
|
|
@@ -563,6 +574,17 @@ export const bodyPartParameters = sqliteTable("body_part_parameter", {
|
|
|
563
574
|
}, (table) => [
|
|
564
575
|
index("body_part_parameter_by_message_id").on(table.messageId, table.bodyPartParameterId),
|
|
565
576
|
]);
|
|
577
|
+
export const bodyStructureRefetches = sqliteTable("body_structure_refetch", {
|
|
578
|
+
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
579
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
580
|
+
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
581
|
+
});
|
|
582
|
+
export const messageSearchTexts = sqliteTable("message_search_text", {
|
|
583
|
+
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
584
|
+
text: text("text").notNull(),
|
|
585
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
586
|
+
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
587
|
+
});
|
|
566
588
|
export const rawMessageStorages = sqliteTable("raw_message_storage", {
|
|
567
589
|
rawStorageId: text("raw_storage_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
568
590
|
messageId: text("message_id").notNull(),
|
|
@@ -597,17 +619,6 @@ export const bodyPartStorages = sqliteTable("body_part_storage", {
|
|
|
597
619
|
}, (table) => [
|
|
598
620
|
index("body_part_storage_by_message_id").on(table.messageId, table.bodyPartStorageId),
|
|
599
621
|
]);
|
|
600
|
-
export const bodyPartContents = sqliteTable("body_part_content", {
|
|
601
|
-
bodyPartContentId: text("body_part_content_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
602
|
-
messageId: text("message_id").notNull(),
|
|
603
|
-
bodyPartId: text("body_part_id").notNull(),
|
|
604
|
-
content: text("content").notNull(),
|
|
605
|
-
contentLength: integer("content_length", { mode: "number" }).notNull(),
|
|
606
|
-
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
607
|
-
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
608
|
-
}, (table) => [
|
|
609
|
-
index("body_part_content_by_message_id").on(table.messageId, table.bodyPartContentId),
|
|
610
|
-
]);
|
|
611
622
|
export const calendarEventIndexes = sqliteTable("calendar_event_index", {
|
|
612
623
|
calendarId: text("calendar_id").notNull(),
|
|
613
624
|
calendarObjectId: text("calendar_object_id").notNull(),
|
|
@@ -648,15 +659,3 @@ export const messageLabels = sqliteTable("message_label", {
|
|
|
648
659
|
index("message_label_by_label_id").on(table.accountConfigId, table.labelId, table.createdAt),
|
|
649
660
|
index("message_label_by_message_id").on(table.messageId, table.labelId),
|
|
650
661
|
]);
|
|
651
|
-
export const filterAnchors = sqliteTable("filter_anchor", {
|
|
652
|
-
accountConfigId: text("account_config_id").notNull(),
|
|
653
|
-
filterId: text("filter_id").notNull(),
|
|
654
|
-
anchorEmbedding: text("anchor_embedding", { mode: "json" }).notNull(),
|
|
655
|
-
anchorEmbeddingId: text("anchor_embedding_id").notNull(),
|
|
656
|
-
anchorSourceText: text("anchor_source_text").notNull(),
|
|
657
|
-
anchorMessageId: text("anchor_message_id").notNull(),
|
|
658
|
-
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
659
|
-
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
660
|
-
}, (table) => [
|
|
661
|
-
primaryKey({ name: "filter_anchor_pk", columns: [table.accountConfigId, table.filterId] }),
|
|
662
|
-
]);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
|
-
/** UUID column stored as text, reads/writes as base36 */
|
|
1
|
+
/** UUID column stored as text in the 36-character hyphenated form, reads/writes as base36 */
|
|
2
|
+
export declare const canonicalUuid: {
|
|
3
|
+
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
4
|
+
name: "";
|
|
5
|
+
dataType: "custom";
|
|
6
|
+
columnType: "SQLiteCustomColumn";
|
|
7
|
+
data: string;
|
|
8
|
+
driverParam: string;
|
|
9
|
+
enumValues: undefined;
|
|
10
|
+
}>;
|
|
11
|
+
<TConfig extends Record<string, any>>(fieldConfig?: TConfig): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
12
|
+
name: "";
|
|
13
|
+
dataType: "custom";
|
|
14
|
+
columnType: "SQLiteCustomColumn";
|
|
15
|
+
data: string;
|
|
16
|
+
driverParam: string;
|
|
17
|
+
enumValues: undefined;
|
|
18
|
+
}>;
|
|
19
|
+
<TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
20
|
+
name: TName;
|
|
21
|
+
dataType: "custom";
|
|
22
|
+
columnType: "SQLiteCustomColumn";
|
|
23
|
+
data: string;
|
|
24
|
+
driverParam: string;
|
|
25
|
+
enumValues: undefined;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
/** UUID column stored as text in the 25-character base36 form, reads/writes as base36 */
|
|
2
29
|
export declare const base36Uuid: {
|
|
3
30
|
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
4
31
|
name: "";
|
|
@@ -25,6 +52,33 @@ export declare const base36Uuid: {
|
|
|
25
52
|
enumValues: undefined;
|
|
26
53
|
}>;
|
|
27
54
|
};
|
|
55
|
+
/** UUID column stored as a 16-byte blob, reads/writes as base36 */
|
|
56
|
+
export declare const rawUuid: {
|
|
57
|
+
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
58
|
+
name: "";
|
|
59
|
+
dataType: "custom";
|
|
60
|
+
columnType: "SQLiteCustomColumn";
|
|
61
|
+
data: string;
|
|
62
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
63
|
+
enumValues: undefined;
|
|
64
|
+
}>;
|
|
65
|
+
<TConfig extends Record<string, any>>(fieldConfig?: TConfig): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
66
|
+
name: "";
|
|
67
|
+
dataType: "custom";
|
|
68
|
+
columnType: "SQLiteCustomColumn";
|
|
69
|
+
data: string;
|
|
70
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
71
|
+
enumValues: undefined;
|
|
72
|
+
}>;
|
|
73
|
+
<TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
74
|
+
name: TName;
|
|
75
|
+
dataType: "custom";
|
|
76
|
+
columnType: "SQLiteCustomColumn";
|
|
77
|
+
data: string;
|
|
78
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
79
|
+
enumValues: undefined;
|
|
80
|
+
}>;
|
|
81
|
+
};
|
|
28
82
|
export declare function generateBase36Id(): string;
|
|
29
83
|
export declare const nullableText: {
|
|
30
84
|
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
@@ -104,3 +158,29 @@ export declare const nullableReal: {
|
|
|
104
158
|
enumValues: undefined;
|
|
105
159
|
}>;
|
|
106
160
|
};
|
|
161
|
+
export declare const nullableBlob: {
|
|
162
|
+
(): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
163
|
+
name: "";
|
|
164
|
+
dataType: "custom";
|
|
165
|
+
columnType: "SQLiteCustomColumn";
|
|
166
|
+
data: Uint8Array<ArrayBufferLike>;
|
|
167
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
168
|
+
enumValues: undefined;
|
|
169
|
+
}>;
|
|
170
|
+
<TConfig extends Record<string, any>>(fieldConfig?: TConfig): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
171
|
+
name: "";
|
|
172
|
+
dataType: "custom";
|
|
173
|
+
columnType: "SQLiteCustomColumn";
|
|
174
|
+
data: Uint8Array<ArrayBufferLike>;
|
|
175
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
176
|
+
enumValues: undefined;
|
|
177
|
+
}>;
|
|
178
|
+
<TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/sqlite-core").SQLiteCustomColumnBuilder<{
|
|
179
|
+
name: TName;
|
|
180
|
+
dataType: "custom";
|
|
181
|
+
columnType: "SQLiteCustomColumn";
|
|
182
|
+
data: Uint8Array<ArrayBufferLike>;
|
|
183
|
+
driverParam: Uint8Array<ArrayBufferLike>;
|
|
184
|
+
enumValues: undefined;
|
|
185
|
+
}>;
|
|
186
|
+
};
|
package/dist/types.js
CHANGED
|
@@ -1,14 +1,140 @@
|
|
|
1
1
|
import { customType } from "drizzle-orm/sqlite-core";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
2
|
+
const base36Digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
3
|
+
const hexDigits = "0123456789abcdef";
|
|
4
|
+
const base36Values = (() => {
|
|
5
|
+
const table = new Int8Array(128).fill(-1);
|
|
6
|
+
for (let i = 0; i < base36Digits.length; i += 1)
|
|
7
|
+
table[base36Digits.charCodeAt(i)] = i;
|
|
8
|
+
return table;
|
|
9
|
+
})();
|
|
10
|
+
const hexValues = (() => {
|
|
11
|
+
const table = new Int8Array(128).fill(-1);
|
|
12
|
+
for (let i = 0; i < hexDigits.length; i += 1) {
|
|
13
|
+
table[hexDigits.charCodeAt(i)] = i;
|
|
14
|
+
table[hexDigits.toUpperCase().charCodeAt(i)] = i;
|
|
15
|
+
}
|
|
16
|
+
return table;
|
|
17
|
+
})();
|
|
18
|
+
const hexOctets = (() => {
|
|
19
|
+
const table = [];
|
|
20
|
+
for (let i = 0; i < 256; i += 1)
|
|
21
|
+
table.push(i.toString(16).padStart(2, "0"));
|
|
22
|
+
return table;
|
|
23
|
+
})();
|
|
24
|
+
const base36Scales = [1, 36, 1296, 46656, 1679616, 60466176];
|
|
25
|
+
function readBase36(id, start, count) {
|
|
26
|
+
let value = 0;
|
|
27
|
+
for (let i = start; i < start + count; i += 1) {
|
|
28
|
+
const code = id.charCodeAt(i);
|
|
29
|
+
const digit = code < 128 ? base36Values[code] : -1;
|
|
30
|
+
if (digit < 0)
|
|
31
|
+
throw new Error(`Not a base36 uuid: ${id}`);
|
|
32
|
+
value = value * 36 + digit;
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
function scaleAndAdd(limbs, scale, addend) {
|
|
37
|
+
let carry = addend;
|
|
38
|
+
for (let i = 7; i >= 0; i -= 1) {
|
|
39
|
+
const product = limbs[i] * scale + carry;
|
|
40
|
+
const low = product % 65536;
|
|
41
|
+
limbs[i] = low;
|
|
42
|
+
carry = (product - low) / 65536;
|
|
43
|
+
}
|
|
44
|
+
return carry;
|
|
45
|
+
}
|
|
46
|
+
function base36ToBytes(id) {
|
|
47
|
+
if (id.length === 0 || id.length > 25)
|
|
48
|
+
throw new Error(`Not a base36 uuid: ${id}`);
|
|
49
|
+
const limbs = new Uint32Array(8);
|
|
50
|
+
const head = id.length % 5;
|
|
51
|
+
if (head > 0 && scaleAndAdd(limbs, base36Scales[head], readBase36(id, 0, head)) !== 0) {
|
|
52
|
+
throw new Error(`base36 uuid does not fit in 128 bits: ${id}`);
|
|
53
|
+
}
|
|
54
|
+
for (let cursor = head; cursor < id.length; cursor += 5) {
|
|
55
|
+
if (scaleAndAdd(limbs, 60466176, readBase36(id, cursor, 5)) !== 0) {
|
|
56
|
+
throw new Error(`base36 uuid does not fit in 128 bits: ${id}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const bytes = new Uint8Array(16);
|
|
60
|
+
for (let i = 0; i < 8; i += 1) {
|
|
61
|
+
bytes[i * 2] = limbs[i] >>> 8;
|
|
62
|
+
bytes[i * 2 + 1] = limbs[i] & 0xff;
|
|
63
|
+
}
|
|
64
|
+
return bytes;
|
|
65
|
+
}
|
|
66
|
+
function bytesToBase36(bytes) {
|
|
67
|
+
if (bytes.length !== 16)
|
|
68
|
+
throw new Error(`Not a 16-byte uuid: ${bytes.length} bytes`);
|
|
69
|
+
const limbs = new Uint32Array(8);
|
|
70
|
+
for (let i = 0; i < 8; i += 1)
|
|
71
|
+
limbs[i] = (bytes[i * 2] << 8) | bytes[i * 2 + 1];
|
|
72
|
+
let id = "";
|
|
73
|
+
for (let chunk = 0; chunk < 5; chunk += 1) {
|
|
74
|
+
let remainder = 0;
|
|
75
|
+
for (let i = 0; i < 8; i += 1) {
|
|
76
|
+
const current = remainder * 65536 + limbs[i];
|
|
77
|
+
const quotient = Math.floor(current / 60466176);
|
|
78
|
+
limbs[i] = quotient;
|
|
79
|
+
remainder = current - quotient * 60466176;
|
|
80
|
+
}
|
|
81
|
+
let piece = "";
|
|
82
|
+
for (let i = 0; i < 5; i += 1) {
|
|
83
|
+
const digit = remainder % 36;
|
|
84
|
+
piece = base36Digits[digit] + piece;
|
|
85
|
+
remainder = (remainder - digit) / 36;
|
|
86
|
+
}
|
|
87
|
+
id = piece + id;
|
|
88
|
+
}
|
|
89
|
+
return id;
|
|
90
|
+
}
|
|
91
|
+
function uuidToBytes(uuid) {
|
|
92
|
+
const bytes = new Uint8Array(16);
|
|
93
|
+
let cursor = 0;
|
|
94
|
+
for (let i = 0; i < 16; i += 1) {
|
|
95
|
+
if (uuid.charCodeAt(cursor) === 45)
|
|
96
|
+
cursor += 1;
|
|
97
|
+
const high = readHex(uuid, cursor);
|
|
98
|
+
const low = readHex(uuid, cursor + 1);
|
|
99
|
+
bytes[i] = (high << 4) | low;
|
|
100
|
+
cursor += 2;
|
|
101
|
+
}
|
|
102
|
+
if (cursor !== uuid.length)
|
|
103
|
+
throw new Error(`Not a uuid: ${uuid}`);
|
|
104
|
+
return bytes;
|
|
105
|
+
}
|
|
106
|
+
function readHex(uuid, index) {
|
|
107
|
+
const code = uuid.charCodeAt(index);
|
|
108
|
+
const value = code < 128 ? hexValues[code] : -1;
|
|
109
|
+
if (value < 0)
|
|
110
|
+
throw new Error(`Not a uuid: ${uuid}`);
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
function bytesToUuid(bytes) {
|
|
114
|
+
return `${hexOctets[bytes[0]]}${hexOctets[bytes[1]]}${hexOctets[bytes[2]]}${hexOctets[bytes[3]]}-${hexOctets[bytes[4]]}${hexOctets[bytes[5]]}-${hexOctets[bytes[6]]}${hexOctets[bytes[7]]}-${hexOctets[bytes[8]]}${hexOctets[bytes[9]]}-${hexOctets[bytes[10]]}${hexOctets[bytes[11]]}${hexOctets[bytes[12]]}${hexOctets[bytes[13]]}${hexOctets[bytes[14]]}${hexOctets[bytes[15]]}`;
|
|
115
|
+
}
|
|
116
|
+
/** UUID column stored as text in the 36-character hyphenated form, reads/writes as base36 */
|
|
117
|
+
export const canonicalUuid = customType({
|
|
118
|
+
dataType: () => "text",
|
|
119
|
+
toDriver: (value) => bytesToUuid(base36ToBytes(value)),
|
|
120
|
+
fromDriver: (value) => bytesToBase36(uuidToBytes(value)),
|
|
121
|
+
});
|
|
122
|
+
/** UUID column stored as text in the 25-character base36 form, reads/writes as base36 */
|
|
5
123
|
export const base36Uuid = customType({
|
|
6
124
|
dataType: () => "text",
|
|
7
|
-
|
|
8
|
-
|
|
125
|
+
});
|
|
126
|
+
/** UUID column stored as a 16-byte blob, reads/writes as base36 */
|
|
127
|
+
export const rawUuid = customType({
|
|
128
|
+
dataType: () => "blob",
|
|
129
|
+
toDriver: (value) => base36ToBytes(value),
|
|
130
|
+
fromDriver: (value) => bytesToBase36(value),
|
|
9
131
|
});
|
|
10
132
|
export function generateBase36Id() {
|
|
11
|
-
|
|
133
|
+
const bytes = new Uint8Array(16);
|
|
134
|
+
crypto.getRandomValues(bytes);
|
|
135
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
136
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
137
|
+
return bytesToBase36(bytes);
|
|
12
138
|
}
|
|
13
139
|
export const nullableText = customType({
|
|
14
140
|
dataType: () => "text",
|
|
@@ -22,3 +148,7 @@ export const nullableReal = customType({
|
|
|
22
148
|
dataType: () => "real",
|
|
23
149
|
fromDriver: (v) => v ?? undefined,
|
|
24
150
|
});
|
|
151
|
+
export const nullableBlob = customType({
|
|
152
|
+
dataType: () => "blob",
|
|
153
|
+
fromDriver: (v) => v ?? undefined,
|
|
154
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remit/drizzle-sqlite-schema",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.36",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,9 +15,6 @@
|
|
|
15
15
|
"build": "tsc",
|
|
16
16
|
"prepare": "tsc"
|
|
17
17
|
},
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"short-uuid": "^5.2.0"
|
|
20
|
-
},
|
|
21
18
|
"peerDependencies": {
|
|
22
19
|
"drizzle-orm": ">=0.30.0",
|
|
23
20
|
"typescript": ">=5.0.0"
|
package/schema.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { index, integer, primaryKey,
|
|
1
|
+
import { index, integer, primaryKey, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
2
2
|
import { generateBase36Id, nullableInteger, nullableText } from "./types.js";
|
|
3
3
|
|
|
4
4
|
export const accountExportRequests = sqliteTable(
|
|
@@ -52,6 +52,25 @@ export const quarantines = sqliteTable(
|
|
|
52
52
|
],
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
+
export const syncWarnings = sqliteTable(
|
|
56
|
+
"sync_warning",
|
|
57
|
+
{
|
|
58
|
+
syncWarningId: text("sync_warning_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
59
|
+
accountConfigId: text("account_config_id").notNull(),
|
|
60
|
+
accountId: text("account_id").notNull(),
|
|
61
|
+
mailboxId: text("mailbox_id").notNull(),
|
|
62
|
+
uidValidity: integer("uid_validity", { mode: "number" }).notNull(),
|
|
63
|
+
uid: integer("uid", { mode: "number" }).notNull(),
|
|
64
|
+
stage: text("stage").$type<"Header" | "Body">().notNull(),
|
|
65
|
+
attempts: integer("attempts").notNull(),
|
|
66
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
67
|
+
},
|
|
68
|
+
(table) => [
|
|
69
|
+
index("sync_warning_by_mailbox_id").on(table.mailboxId),
|
|
70
|
+
index("sync_warning_by_account_config_id").on(table.accountConfigId, table.createdAt),
|
|
71
|
+
],
|
|
72
|
+
);
|
|
73
|
+
|
|
55
74
|
export const accountConfigs = sqliteTable(
|
|
56
75
|
"account_config",
|
|
57
76
|
{
|
|
@@ -156,11 +175,10 @@ export const filters = sqliteTable(
|
|
|
156
175
|
ttl: integer("ttl", { mode: "number" }),
|
|
157
176
|
state: text("state").$type<"Active" | "Expired" | "Disabled">().notNull().default("Active"),
|
|
158
177
|
disabledReason: text("disabled_reason").$type<"None" | "UserDisabled" | "AwaitingFolder" | "FolderCreateFailed" | "FolderMissing">().notNull().default("None"),
|
|
159
|
-
hasAnchor: integer("has_anchor", { mode: "boolean" }).notNull().default(false),
|
|
160
178
|
ruleChangedAt: integer("rule_changed_at", { mode: "number" }).notNull(),
|
|
161
179
|
actionChangedAt: integer("action_changed_at", { mode: "number" }).notNull(),
|
|
162
180
|
matchOperator: text("match_operator").$type<"And" | "Or">().notNull().default("And"),
|
|
163
|
-
literalClauses: text("literal_clauses", { mode: "json" }).notNull()
|
|
181
|
+
literalClauses: text("literal_clauses", { mode: "json" }).notNull(),
|
|
164
182
|
actionLabelId: text("action_label_id").notNull().default("None"),
|
|
165
183
|
actionMailboxId: text("action_mailbox_id").notNull().default("None"),
|
|
166
184
|
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
@@ -197,10 +215,8 @@ export const organizeJobRequests = sqliteTable(
|
|
|
197
215
|
userId: text("user_id").notNull(),
|
|
198
216
|
state: text("state").$type<"Pending" | "Running" | "Complete" | "Failed">().notNull().default("Pending"),
|
|
199
217
|
filterId: text("filter_id").notNull().default("None"),
|
|
200
|
-
anchorMessageId: text("anchor_message_id").notNull().default("None"),
|
|
201
218
|
matchOperator: text("match_operator").$type<"And" | "Or">().notNull().default("And"),
|
|
202
219
|
literalClauses: text("literal_clauses", { mode: "json" }).notNull().default([]),
|
|
203
|
-
similarityThreshold: real("similarity_threshold").notNull().default(0.75),
|
|
204
220
|
actionLabelId: text("action_label_id").notNull().default("None"),
|
|
205
221
|
actionMailboxId: text("action_mailbox_id").notNull().default("None"),
|
|
206
222
|
matchedCount: integer("matched_count").notNull().default(0),
|
|
@@ -389,10 +405,11 @@ export const addresses = sqliteTable(
|
|
|
389
405
|
},
|
|
390
406
|
(table) => [
|
|
391
407
|
index("address_by_account_config_id").on(table.accountConfigId, table.normalizedCompound),
|
|
408
|
+
index("address_by_normalized_email").on(table.accountConfigId, table.normalizedEmail),
|
|
392
409
|
],
|
|
393
410
|
);
|
|
394
411
|
|
|
395
|
-
export const
|
|
412
|
+
export const messageRecords = sqliteTable(
|
|
396
413
|
"message",
|
|
397
414
|
{
|
|
398
415
|
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
@@ -401,7 +418,6 @@ export const messages = sqliteTable(
|
|
|
401
418
|
sequenceNumber: integer("sequence_number").notNull(),
|
|
402
419
|
rfc822Size: integer("rfc822_size", { mode: "number" }).notNull(),
|
|
403
420
|
internalDate: integer("internal_date", { mode: "number" }).notNull(),
|
|
404
|
-
messageIdHeader: nullableText("message_id_header"),
|
|
405
421
|
envelopeId: text("envelope_id").notNull(),
|
|
406
422
|
rootBodyPartId: text("root_body_part_id").notNull(),
|
|
407
423
|
bodyStorageKey: nullableText("body_storage_key"),
|
|
@@ -719,6 +735,19 @@ export const bodyPartParameters = sqliteTable(
|
|
|
719
735
|
],
|
|
720
736
|
);
|
|
721
737
|
|
|
738
|
+
export const bodyStructureRefetches = sqliteTable("body_structure_refetch", {
|
|
739
|
+
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
740
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
741
|
+
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
export const messageSearchTexts = sqliteTable("message_search_text", {
|
|
745
|
+
messageId: text("message_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
746
|
+
text: text("text").notNull(),
|
|
747
|
+
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
748
|
+
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
749
|
+
});
|
|
750
|
+
|
|
722
751
|
export const rawMessageStorages = sqliteTable(
|
|
723
752
|
"raw_message_storage",
|
|
724
753
|
{
|
|
@@ -763,22 +792,6 @@ export const bodyPartStorages = sqliteTable(
|
|
|
763
792
|
],
|
|
764
793
|
);
|
|
765
794
|
|
|
766
|
-
export const bodyPartContents = sqliteTable(
|
|
767
|
-
"body_part_content",
|
|
768
|
-
{
|
|
769
|
-
bodyPartContentId: text("body_part_content_id").primaryKey().$defaultFn(() => generateBase36Id()),
|
|
770
|
-
messageId: text("message_id").notNull(),
|
|
771
|
-
bodyPartId: text("body_part_id").notNull(),
|
|
772
|
-
content: text("content").notNull(),
|
|
773
|
-
contentLength: integer("content_length", { mode: "number" }).notNull(),
|
|
774
|
-
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
775
|
-
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
776
|
-
},
|
|
777
|
-
(table) => [
|
|
778
|
-
index("body_part_content_by_message_id").on(table.messageId, table.bodyPartContentId),
|
|
779
|
-
],
|
|
780
|
-
);
|
|
781
|
-
|
|
782
795
|
export const calendarEventIndexes = sqliteTable(
|
|
783
796
|
"calendar_event_index",
|
|
784
797
|
{
|
|
@@ -833,20 +846,3 @@ export const messageLabels = sqliteTable(
|
|
|
833
846
|
index("message_label_by_message_id").on(table.messageId, table.labelId),
|
|
834
847
|
],
|
|
835
848
|
);
|
|
836
|
-
|
|
837
|
-
export const filterAnchors = sqliteTable(
|
|
838
|
-
"filter_anchor",
|
|
839
|
-
{
|
|
840
|
-
accountConfigId: text("account_config_id").notNull(),
|
|
841
|
-
filterId: text("filter_id").notNull(),
|
|
842
|
-
anchorEmbedding: text("anchor_embedding", { mode: "json" }).notNull(),
|
|
843
|
-
anchorEmbeddingId: text("anchor_embedding_id").notNull(),
|
|
844
|
-
anchorSourceText: text("anchor_source_text").notNull(),
|
|
845
|
-
anchorMessageId: text("anchor_message_id").notNull(),
|
|
846
|
-
createdAt: integer("created_at", { mode: "number" }).notNull(),
|
|
847
|
-
updatedAt: integer("updated_at", { mode: "number" }).notNull(),
|
|
848
|
-
},
|
|
849
|
-
(table) => [
|
|
850
|
-
primaryKey({ name: "filter_anchor_pk", columns: [table.accountConfigId, table.filterId] }),
|
|
851
|
-
],
|
|
852
|
-
);
|