@lunora/d1 1.0.0-alpha.18 → 1.0.0-alpha.180

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.
@@ -1,142 +0,0 @@
1
- import { runD1GlobalTableMigrations } from './createD1CtxDb-BMR8J0dT.mjs';
2
- import { decodeGlobalRow } from '@lunora/sql-store';
3
-
4
- const ensureGlobalTables = (exec, schema) => runD1GlobalTableMigrations(exec, schema);
5
- const DEFAULT_PAGE_SIZE = 50;
6
- const MAX_PAGE_SIZE = 500;
7
- const DEFAULT_FACET_LIMIT = 30;
8
- const MAX_FACET_LIMIT = 200;
9
- const quoteIdentifier = (name) => `"${name.replaceAll('"', '""')}"`;
10
- const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
11
- const INTERNAL_TABLE = /^sqlite_|^_cf_|^d1_|^__cdc|__agg_|__rank_|__fts_/u;
12
- const isInternalTable = (name) => INTERNAL_TABLE.test(name);
13
- const SENSITIVE_COLUMN = /password|secret|token|hash|salt|credential/iu;
14
- const listTableNames = async (exec) => {
15
- const rows = await exec.all("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name", []);
16
- return rows.map((row) => String(row["name"])).filter((name) => !isInternalTable(name));
17
- };
18
- const countRows = async (exec, quotedTable, whereSql = "", whereParams = []) => {
19
- const rows = await exec.all(`SELECT COUNT(*) AS c FROM ${quotedTable}${whereSql}`, whereParams);
20
- return Number(rows[0]?.["c"] ?? 0);
21
- };
22
- const physicalColumnName = (schema, table, displayColumn) => schema.tables[table] !== void 0 && displayColumn === "_id" ? "id" : displayColumn;
23
- const buildEqPredicate = (schema, table, displayColumns, filters) => {
24
- if (filters === void 0 || filters.length === 0) {
25
- return void 0;
26
- }
27
- const clauses = [];
28
- const params = [];
29
- for (const filter of filters) {
30
- if (!displayColumns.includes(filter.column)) {
31
- throw Object.assign(new Error(`unknown column: ${filter.column}`), { code: "UNKNOWN_COLUMN", name: "LunoraError", status: 404 });
32
- }
33
- const quoted = quoteIdentifier(physicalColumnName(schema, table, filter.column));
34
- if (filter.value === null || filter.value === void 0) {
35
- clauses.push(`${quoted} IS NULL`);
36
- } else {
37
- clauses.push(`${quoted} = ?`);
38
- params.push(filter.value);
39
- }
40
- }
41
- return { params, where: clauses.join(" AND ") };
42
- };
43
- const decodeRow = (schema, table, row) => {
44
- const definition = schema.tables[table];
45
- if (definition) {
46
- return decodeGlobalRow(definition, row);
47
- }
48
- const redacted = {};
49
- for (const [key, value] of Object.entries(row)) {
50
- redacted[key] = value !== null && value !== void 0 && SENSITIVE_COLUMN.test(key) ? "•••" : value;
51
- }
52
- return redacted;
53
- };
54
- const resolveColumns = async (exec, schema, table) => {
55
- const definition = schema.tables[table];
56
- if (definition) {
57
- return ["_id", "_creationTime", ...Object.keys(definition.shape)];
58
- }
59
- const info = await exec.all(`PRAGMA table_info(${quoteIdentifier(table)})`, []);
60
- return info.map((column) => String(column["name"]));
61
- };
62
- const resolveReferences = async (exec, schema, table) => {
63
- if (schema.tables[table]) {
64
- return void 0;
65
- }
66
- const rows = await exec.all(`PRAGMA foreign_key_list(${quoteIdentifier(table)})`, []);
67
- if (rows.length === 0) {
68
- return void 0;
69
- }
70
- const references = {};
71
- for (const row of rows) {
72
- const from = String(row["from"]);
73
- const target = String(row["table"]);
74
- references[from] ??= target;
75
- }
76
- return references;
77
- };
78
- const listGlobalTables = async (exec, schema) => {
79
- await ensureGlobalTables(exec, schema);
80
- const names = await listTableNames(exec);
81
- return Promise.all(
82
- names.map(async (name) => {
83
- return { name, rowCount: await countRows(exec, quoteIdentifier(name)) };
84
- })
85
- );
86
- };
87
- const readGlobalTablePage = async (exec, schema, options) => {
88
- const { table } = options;
89
- await ensureGlobalTables(exec, schema);
90
- const tableNames = await listTableNames(exec);
91
- if (!tableNames.includes(table)) {
92
- throw Object.assign(new Error(`unknown table: ${table}`), { code: "UNKNOWN_TABLE", name: "LunoraError", status: 404 });
93
- }
94
- const limit = clamp(Math.trunc(options.limit ?? DEFAULT_PAGE_SIZE), 1, MAX_PAGE_SIZE);
95
- const offset = Math.max(0, Math.trunc(options.offset ?? 0));
96
- const quoted = quoteIdentifier(table);
97
- const columns = await resolveColumns(exec, schema, table);
98
- const predicate = buildEqPredicate(schema, table, columns, options.filters);
99
- const whereSql = predicate === void 0 ? "" : ` WHERE ${predicate.where}`;
100
- const whereParams = predicate?.params ?? [];
101
- const total = await countRows(exec, quoted, whereSql, whereParams);
102
- const raw = await exec.all(`SELECT * FROM ${quoted}${whereSql} LIMIT ? OFFSET ?`, [...whereParams, limit, offset]);
103
- const rows = raw.map((row) => decodeRow(schema, table, row));
104
- const references = await resolveReferences(exec, schema, table);
105
- return references === void 0 ? { columns, rows, total } : { columns, refs: references, rows, total };
106
- };
107
- const facetGlobalColumn = async (exec, schema, options) => {
108
- const { column, table } = options;
109
- await ensureGlobalTables(exec, schema);
110
- const tableNames = await listTableNames(exec);
111
- if (!tableNames.includes(table)) {
112
- throw Object.assign(new Error(`unknown table: ${table}`), { code: "UNKNOWN_TABLE", name: "LunoraError", status: 404 });
113
- }
114
- const columns = await resolveColumns(exec, schema, table);
115
- if (!columns.includes(column)) {
116
- throw Object.assign(new Error(`unknown column: ${column}`), { code: "UNKNOWN_COLUMN", name: "LunoraError", status: 404 });
117
- }
118
- const quoted = quoteIdentifier(table);
119
- const predicate = buildEqPredicate(schema, table, columns, options.filters);
120
- const whereSql = predicate === void 0 ? "" : ` WHERE ${predicate.where}`;
121
- const whereParams = predicate?.params ?? [];
122
- if (schema.tables[table] === void 0 && SENSITIVE_COLUMN.test(column)) {
123
- const total = await countRows(exec, quoted, whereSql, whereParams);
124
- return { truncated: false, values: total === 0 ? [] : [{ count: total, value: "•••" }] };
125
- }
126
- const limit = clamp(Math.trunc(options.limit ?? DEFAULT_FACET_LIMIT), 1, MAX_FACET_LIMIT);
127
- const physical = quoteIdentifier(physicalColumnName(schema, table, column));
128
- const rows = await exec.all(`SELECT ${physical} AS value, COUNT(*) AS count FROM ${quoted}${whereSql} GROUP BY ${physical} ORDER BY count DESC LIMIT ?`, [
129
- ...whereParams,
130
- limit + 1
131
- ]);
132
- const truncated = rows.length > limit;
133
- const kept = truncated ? rows.slice(0, limit) : rows;
134
- return {
135
- truncated,
136
- values: kept.map((row) => {
137
- return { count: Number(row["count"]), value: row["value"] };
138
- })
139
- };
140
- };
141
-
142
- export { facetGlobalColumn, listGlobalTables, readGlobalTablePage };
@@ -1,3 +0,0 @@
1
- const quoteIdentifier = (name) => `"${name.replaceAll('"', '""')}"`;
2
-
3
- export { quoteIdentifier };
@@ -1,27 +0,0 @@
1
- import { sqliteEncode, sqliteDecode } from '@lunora/sql-store';
2
- import { sql } from 'drizzle-orm';
3
- import { sqlAffinityForKind } from '../dialect.mjs';
4
-
5
- const UNIQUE_VIOLATION_RE = /unique constraint failed/iu;
6
- const sqliteDialect = {
7
- companionTypes: {
8
- autoincrementPrimaryKey: "INTEGER PRIMARY KEY AUTOINCREMENT",
9
- integer: "INTEGER",
10
- key: "TEXT",
11
- real: "REAL",
12
- text: "TEXT"
13
- },
14
- columnType: (kind) => sqlAffinityForKind(kind),
15
- decode: (value, kind) => sqliteDecode(value, kind),
16
- encode: (value) => sqliteEncode(value),
17
- frameworkColumns: () => [
18
- { name: "id", type: "TEXT PRIMARY KEY" },
19
- { name: "_creationTime", type: "REAL NOT NULL" }
20
- ],
21
- isUniqueViolation: (error) => error instanceof Error && UNIQUE_VIOLATION_RE.test(error.message),
22
- name: "sqlite",
23
- supportsReturning: true,
24
- tableExists: (table) => sql`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ${table}`
25
- };
26
-
27
- export { sqliteDialect as default };