@peers-app/peers-sdk 0.1.4
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/README.md +1 -0
- package/dist/context/data-context.d.ts +31 -0
- package/dist/context/data-context.js +56 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.js +19 -0
- package/dist/context/user-context-singleton.d.ts +11 -0
- package/dist/context/user-context-singleton.js +121 -0
- package/dist/context/user-context.d.ts +55 -0
- package/dist/context/user-context.js +205 -0
- package/dist/data/assistants.d.ts +68 -0
- package/dist/data/assistants.js +64 -0
- package/dist/data/change-tracking.d.ts +219 -0
- package/dist/data/change-tracking.js +119 -0
- package/dist/data/channels.d.ts +29 -0
- package/dist/data/channels.js +25 -0
- package/dist/data/data-locks.d.ts +37 -0
- package/dist/data/data-locks.js +180 -0
- package/dist/data/data-locks.test.d.ts +1 -0
- package/dist/data/data-locks.test.js +456 -0
- package/dist/data/device-sync-info.d.ts +19 -0
- package/dist/data/device-sync-info.js +24 -0
- package/dist/data/devices.d.ts +51 -0
- package/dist/data/devices.js +36 -0
- package/dist/data/embeddings.d.ts +47 -0
- package/dist/data/embeddings.js +36 -0
- package/dist/data/files/file-read-stream.d.ts +27 -0
- package/dist/data/files/file-read-stream.js +195 -0
- package/dist/data/files/file-write-stream.d.ts +20 -0
- package/dist/data/files/file-write-stream.js +113 -0
- package/dist/data/files/file.types.d.ts +47 -0
- package/dist/data/files/file.types.js +55 -0
- package/dist/data/files/files.d.ts +28 -0
- package/dist/data/files/files.js +127 -0
- package/dist/data/files/files.test.d.ts +1 -0
- package/dist/data/files/files.test.js +728 -0
- package/dist/data/files/index.d.ts +4 -0
- package/dist/data/files/index.js +23 -0
- package/dist/data/group-member-roles.d.ts +9 -0
- package/dist/data/group-member-roles.js +25 -0
- package/dist/data/group-members.d.ts +39 -0
- package/dist/data/group-members.js +68 -0
- package/dist/data/group-members.test.d.ts +1 -0
- package/dist/data/group-members.test.js +287 -0
- package/dist/data/group-permissions.d.ts +8 -0
- package/dist/data/group-permissions.js +73 -0
- package/dist/data/group-share.d.ts +50 -0
- package/dist/data/group-share.js +196 -0
- package/dist/data/groups.d.ts +50 -0
- package/dist/data/groups.js +73 -0
- package/dist/data/groups.test.d.ts +1 -0
- package/dist/data/groups.test.js +153 -0
- package/dist/data/index.d.ts +31 -0
- package/dist/data/index.js +47 -0
- package/dist/data/knowledge/knowledge-frames.d.ts +34 -0
- package/dist/data/knowledge/knowledge-frames.js +34 -0
- package/dist/data/knowledge/knowledge-links.d.ts +30 -0
- package/dist/data/knowledge/knowledge-links.js +25 -0
- package/dist/data/knowledge/knowledge-values.d.ts +35 -0
- package/dist/data/knowledge/knowledge-values.js +35 -0
- package/dist/data/knowledge/peer-types.d.ts +112 -0
- package/dist/data/knowledge/peer-types.js +27 -0
- package/dist/data/knowledge/predicates.d.ts +34 -0
- package/dist/data/knowledge/predicates.js +27 -0
- package/dist/data/messages.d.ts +57 -0
- package/dist/data/messages.js +97 -0
- package/dist/data/orm/client-proxy.data-source.d.ts +27 -0
- package/dist/data/orm/client-proxy.data-source.js +65 -0
- package/dist/data/orm/cursor.d.ts +25 -0
- package/dist/data/orm/cursor.js +47 -0
- package/dist/data/orm/cursor.test.d.ts +1 -0
- package/dist/data/orm/cursor.test.js +315 -0
- package/dist/data/orm/data-query.d.ts +96 -0
- package/dist/data/orm/data-query.js +208 -0
- package/dist/data/orm/data-query.mongo.d.ts +17 -0
- package/dist/data/orm/data-query.mongo.js +267 -0
- package/dist/data/orm/data-query.mongo.test.d.ts +1 -0
- package/dist/data/orm/data-query.mongo.test.js +398 -0
- package/dist/data/orm/data-query.sqlite.d.ts +14 -0
- package/dist/data/orm/data-query.sqlite.js +297 -0
- package/dist/data/orm/data-query.sqlite.test.d.ts +1 -0
- package/dist/data/orm/data-query.sqlite.test.js +377 -0
- package/dist/data/orm/data-query.test.d.ts +1 -0
- package/dist/data/orm/data-query.test.js +553 -0
- package/dist/data/orm/decorators.d.ts +6 -0
- package/dist/data/orm/decorators.js +21 -0
- package/dist/data/orm/dependency-injection.test.d.ts +1 -0
- package/dist/data/orm/dependency-injection.test.js +171 -0
- package/dist/data/orm/doc.d.ts +26 -0
- package/dist/data/orm/doc.js +124 -0
- package/dist/data/orm/event-registry.d.ts +24 -0
- package/dist/data/orm/event-registry.js +40 -0
- package/dist/data/orm/event-registry.test.d.ts +1 -0
- package/dist/data/orm/event-registry.test.js +44 -0
- package/dist/data/orm/factory.d.ts +8 -0
- package/dist/data/orm/factory.js +147 -0
- package/dist/data/orm/index.d.ts +16 -0
- package/dist/data/orm/index.js +32 -0
- package/dist/data/orm/multi-cursors.d.ts +11 -0
- package/dist/data/orm/multi-cursors.js +146 -0
- package/dist/data/orm/multi-cursors.test.d.ts +1 -0
- package/dist/data/orm/multi-cursors.test.js +455 -0
- package/dist/data/orm/sql-db.d.ts +6 -0
- package/dist/data/orm/sql-db.js +2 -0
- package/dist/data/orm/sql.data-source.d.ts +38 -0
- package/dist/data/orm/sql.data-source.js +379 -0
- package/dist/data/orm/sql.data-source.test.d.ts +1 -0
- package/dist/data/orm/sql.data-source.test.js +406 -0
- package/dist/data/orm/subscribable.data-source.d.ts +25 -0
- package/dist/data/orm/subscribable.data-source.js +72 -0
- package/dist/data/orm/table-container-events.test.d.ts +1 -0
- package/dist/data/orm/table-container-events.test.js +93 -0
- package/dist/data/orm/table-container.d.ts +39 -0
- package/dist/data/orm/table-container.js +96 -0
- package/dist/data/orm/table-definitions.system.d.ts +9 -0
- package/dist/data/orm/table-definitions.system.js +29 -0
- package/dist/data/orm/table-definitions.type.d.ts +19 -0
- package/dist/data/orm/table-definitions.type.js +2 -0
- package/dist/data/orm/table-dependencies.d.ts +32 -0
- package/dist/data/orm/table-dependencies.js +2 -0
- package/dist/data/orm/table.d.ts +42 -0
- package/dist/data/orm/table.event-source.test.d.ts +1 -0
- package/dist/data/orm/table.event-source.test.js +341 -0
- package/dist/data/orm/table.js +244 -0
- package/dist/data/orm/types.d.ts +20 -0
- package/dist/data/orm/types.js +115 -0
- package/dist/data/orm/types.test.d.ts +1 -0
- package/dist/data/orm/types.test.js +71 -0
- package/dist/data/package-permissions.d.ts +7 -0
- package/dist/data/package-permissions.js +18 -0
- package/dist/data/packages.d.ts +92 -0
- package/dist/data/packages.js +90 -0
- package/dist/data/peer-events/peer-event-handlers.d.ts +21 -0
- package/dist/data/peer-events/peer-event-handlers.js +28 -0
- package/dist/data/peer-events/peer-event-types.d.ts +119 -0
- package/dist/data/peer-events/peer-event-types.js +29 -0
- package/dist/data/peer-events/peer-events.d.ts +41 -0
- package/dist/data/peer-events/peer-events.js +102 -0
- package/dist/data/persistent-vars.d.ts +87 -0
- package/dist/data/persistent-vars.js +230 -0
- package/dist/data/tool-tests.d.ts +37 -0
- package/dist/data/tool-tests.js +27 -0
- package/dist/data/tools.d.ts +358 -0
- package/dist/data/tools.js +48 -0
- package/dist/data/user-permissions.d.ts +15 -0
- package/dist/data/user-permissions.js +39 -0
- package/dist/data/user-permissions.test.d.ts +1 -0
- package/dist/data/user-permissions.test.js +252 -0
- package/dist/data/users.d.ts +38 -0
- package/dist/data/users.js +73 -0
- package/dist/data/workflow-logs.d.ts +106 -0
- package/dist/data/workflow-logs.js +67 -0
- package/dist/data/workflow-runs.d.ts +103 -0
- package/dist/data/workflow-runs.js +313 -0
- package/dist/data/workflows.d.ts +16 -0
- package/dist/data/workflows.js +21 -0
- package/dist/device/connection.d.ts +41 -0
- package/dist/device/connection.js +249 -0
- package/dist/device/connection.test.d.ts +1 -0
- package/dist/device/connection.test.js +292 -0
- package/dist/device/device-election.d.ts +36 -0
- package/dist/device/device-election.js +137 -0
- package/dist/device/device.d.ts +22 -0
- package/dist/device/device.js +110 -0
- package/dist/device/device.test.d.ts +1 -0
- package/dist/device/device.test.js +203 -0
- package/dist/device/get-trust-level.d.ts +3 -0
- package/dist/device/get-trust-level.js +87 -0
- package/dist/device/socket.type.d.ts +20 -0
- package/dist/device/socket.type.js +15 -0
- package/dist/device/streamed-socket.d.ts +27 -0
- package/dist/device/streamed-socket.js +154 -0
- package/dist/device/streamed-socket.test.d.ts +1 -0
- package/dist/device/streamed-socket.test.js +44 -0
- package/dist/events.d.ts +35 -0
- package/dist/events.js +128 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +50 -0
- package/dist/keys.d.ts +51 -0
- package/dist/keys.js +234 -0
- package/dist/keys.test.d.ts +1 -0
- package/dist/keys.test.js +215 -0
- package/dist/mentions.d.ts +9 -0
- package/dist/mentions.js +46 -0
- package/dist/observable.d.ts +19 -0
- package/dist/observable.js +112 -0
- package/dist/observable.test.d.ts +1 -0
- package/dist/observable.test.js +183 -0
- package/dist/package-loader/get-require.d.ts +10 -0
- package/dist/package-loader/get-require.js +31 -0
- package/dist/package-loader/index.d.ts +1 -0
- package/dist/package-loader/index.js +17 -0
- package/dist/package-loader/package-loader.d.ts +16 -0
- package/dist/package-loader/package-loader.js +102 -0
- package/dist/peers-ui/peers-ui.d.ts +15 -0
- package/dist/peers-ui/peers-ui.js +23 -0
- package/dist/peers-ui/peers-ui.types.d.ts +35 -0
- package/dist/peers-ui/peers-ui.types.js +3 -0
- package/dist/rpc-types.d.ts +45 -0
- package/dist/rpc-types.js +47 -0
- package/dist/serial-json.d.ts +5 -0
- package/dist/serial-json.js +186 -0
- package/dist/serial-json.test.d.ts +1 -0
- package/dist/serial-json.test.js +86 -0
- package/dist/system-ids.d.ts +6 -0
- package/dist/system-ids.js +10 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/tools-factory.d.ts +5 -0
- package/dist/tools/tools-factory.js +34 -0
- package/dist/types/app-nav.d.ts +18 -0
- package/dist/types/app-nav.js +10 -0
- package/dist/types/assistant-runner-args.d.ts +9 -0
- package/dist/types/assistant-runner-args.js +2 -0
- package/dist/types/field-type.d.ts +37 -0
- package/dist/types/field-type.js +26 -0
- package/dist/types/peer-device.d.ts +40 -0
- package/dist/types/peer-device.js +14 -0
- package/dist/types/peers-package.d.ts +23 -0
- package/dist/types/peers-package.js +2 -0
- package/dist/types/workflow-logger.d.ts +2 -0
- package/dist/types/workflow-logger.js +2 -0
- package/dist/types/workflow-run-context.d.ts +12 -0
- package/dist/types/workflow-run-context.js +2 -0
- package/dist/types/workflow.d.ts +72 -0
- package/dist/types/workflow.js +24 -0
- package/dist/types/zod-types.d.ts +7 -0
- package/dist/types/zod-types.js +12 -0
- package/dist/users.query.d.ts +13 -0
- package/dist/users.query.js +134 -0
- package/dist/utils.d.ts +39 -0
- package/dist/utils.js +240 -0
- package/dist/utils.test.d.ts +1 -0
- package/dist/utils.test.js +140 -0
- package/package.json +50 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SQLDataSource = void 0;
|
|
4
|
+
exports.jsValueToSqlValue = jsValueToSqlValue;
|
|
5
|
+
exports.sqlValueToJsValue = sqlValueToJsValue;
|
|
6
|
+
exports.globalDefaultValues = globalDefaultValues;
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
const serial_json_1 = require("../../serial-json");
|
|
9
|
+
const data_query_1 = require("./data-query");
|
|
10
|
+
const data_query_sqlite_1 = require("./data-query.sqlite");
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
class SQLDataSource {
|
|
13
|
+
db;
|
|
14
|
+
metaData;
|
|
15
|
+
schema;
|
|
16
|
+
tableName;
|
|
17
|
+
primaryKeyName;
|
|
18
|
+
constructor(db, metaData, schema = (0, types_1.fieldsToSchema)(metaData.fields)) {
|
|
19
|
+
this.db = db;
|
|
20
|
+
this.metaData = metaData;
|
|
21
|
+
this.schema = schema;
|
|
22
|
+
this.tableName = (0, utils_1.getFullTableName)(metaData);
|
|
23
|
+
this.primaryKeyName = metaData.primaryKeyName;
|
|
24
|
+
const primaryKeyIsValid = metaData.fields.find(f => f.name === metaData.primaryKeyName);
|
|
25
|
+
if (!primaryKeyIsValid) {
|
|
26
|
+
throw new Error(`Table "${this.tableName}", primary key "${metaData.primaryKeyName}" is not a valid field name`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
buildTableSql() {
|
|
30
|
+
let fieldsSql = [];
|
|
31
|
+
for (const field of this.metaData.fields) {
|
|
32
|
+
let sqlType = "";
|
|
33
|
+
switch (field.type) {
|
|
34
|
+
case 'id':
|
|
35
|
+
// consider using: `id TEXT NOT NULL CHECK (length(id) = 25)
|
|
36
|
+
sqlType = 'TEXT';
|
|
37
|
+
break;
|
|
38
|
+
case 'string':
|
|
39
|
+
sqlType = 'TEXT';
|
|
40
|
+
break;
|
|
41
|
+
case 'number':
|
|
42
|
+
sqlType = 'REAL';
|
|
43
|
+
break;
|
|
44
|
+
case 'boolean':
|
|
45
|
+
sqlType = 'INTEGER';
|
|
46
|
+
break;
|
|
47
|
+
case 'Date':
|
|
48
|
+
sqlType = 'TEXT';
|
|
49
|
+
break;
|
|
50
|
+
case 'object':
|
|
51
|
+
sqlType = 'TEXT';
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
sqlType = 'TEXT';
|
|
55
|
+
}
|
|
56
|
+
let options = field.optional ? 'NULL' : 'NOT NULL';
|
|
57
|
+
if (field.name === this.metaData.primaryKeyName) {
|
|
58
|
+
options += ' PRIMARY KEY';
|
|
59
|
+
}
|
|
60
|
+
fieldsSql.push(`"${field.name}" ${sqlType} ${options}`);
|
|
61
|
+
}
|
|
62
|
+
// const fields = this.dataType.fields.map(f => `${f.name} ${f.type}`).join(', ');
|
|
63
|
+
const fields = fieldsSql.join(',\n');
|
|
64
|
+
const sql = [
|
|
65
|
+
`CREATE TABLE IF NOT EXISTS "${this.tableName}" (`,
|
|
66
|
+
` ${fields}`,
|
|
67
|
+
`) WITHOUT ROWID`,
|
|
68
|
+
].join('\n');
|
|
69
|
+
return sql;
|
|
70
|
+
}
|
|
71
|
+
async ensureTableAndIndexesExist() {
|
|
72
|
+
// create table if not exists
|
|
73
|
+
const sql = this.buildTableSql();
|
|
74
|
+
await this.db.exec(sql, []);
|
|
75
|
+
const indexNames = [];
|
|
76
|
+
// create indexes if they don't exist
|
|
77
|
+
if (this.metaData.indexes) {
|
|
78
|
+
for (const index of this.metaData.indexes) {
|
|
79
|
+
let fieldNames = '';
|
|
80
|
+
const fields = index.fields.map(f => {
|
|
81
|
+
if (typeof f === 'string') {
|
|
82
|
+
fieldNames += '_' + f;
|
|
83
|
+
return f;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
fieldNames += '_' + f.name;
|
|
87
|
+
return `${f.name} ${f.order}`;
|
|
88
|
+
}
|
|
89
|
+
}).join(', ');
|
|
90
|
+
const hash = (0, utils_1.simpleHash)(JSON.stringify(index));
|
|
91
|
+
const unique = index.unique ? 'UNIQUE' : '';
|
|
92
|
+
const indexName = `${this.tableName}_${fieldNames}_${hash}`;
|
|
93
|
+
indexNames.push(indexName);
|
|
94
|
+
const sql = `CREATE ${unique} INDEX IF NOT EXISTS "${indexName}" ON "${this.tableName}"(${fields});`;
|
|
95
|
+
try {
|
|
96
|
+
await this.db.exec(sql, []);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
console.error(`Error creating index "${indexName}" on table "${this.tableName}": ${String(e)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// remove indexes that are no longer specified in the schema
|
|
104
|
+
const existingIndexes = (await this.db.all(`PRAGMA index_list("${this.tableName}")`, [])) || [];
|
|
105
|
+
for (const existingIndex of existingIndexes) {
|
|
106
|
+
const indexName = existingIndex.name;
|
|
107
|
+
if (!indexNames.includes(indexName) && !indexName.startsWith('sqlite_autoindex_')) {
|
|
108
|
+
console.log(`Dropping index "${indexName}" because it's no longer in the schema.`);
|
|
109
|
+
const sql = `DROP INDEX IF EXISTS "${indexName}"`;
|
|
110
|
+
await this.db.exec(sql, []);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async ensureTableIsNewest() {
|
|
115
|
+
const now = new Date();
|
|
116
|
+
await this.ensureTableAndIndexesExist();
|
|
117
|
+
let newestTableDef = this.buildTableSql();
|
|
118
|
+
newestTableDef = newestTableDef.replace(/CREATE TABLE IF NOT EXISTS/, 'CREATE TABLE');
|
|
119
|
+
const sqlGetTableRecord = `SELECT * FROM sqlite_master WHERE type = 'table' AND name = '${this.tableName}'`;
|
|
120
|
+
const table = await this.db.get(sqlGetTableRecord, []);
|
|
121
|
+
const existingTableDef = table?.sql || '';
|
|
122
|
+
if (newestTableDef !== existingTableDef) {
|
|
123
|
+
console.log(`Table "${this.tableName}" is out of date, updating...`);
|
|
124
|
+
// rename table
|
|
125
|
+
const tempTableName = this.tableName + `_old_${now.getTime()}`;
|
|
126
|
+
const renameSql = `ALTER TABLE "${this.tableName}" RENAME TO "${tempTableName}"`;
|
|
127
|
+
await this.db.exec(renameSql, []);
|
|
128
|
+
// create new table
|
|
129
|
+
await this.ensureTableAndIndexesExist();
|
|
130
|
+
// sql query to copy existing data and set new required fields to default values
|
|
131
|
+
const defaults = this.initRecord();
|
|
132
|
+
const fieldsInsert = this.metaData.fields.map(f => `"${f.name}"`).join(', ');
|
|
133
|
+
const fieldsSelect = this.metaData.fields.map(f => {
|
|
134
|
+
const existingField = existingTableDef.includes(`"${f.name}"`);
|
|
135
|
+
if (existingField && f.optional) {
|
|
136
|
+
return `"${f.name}"`;
|
|
137
|
+
}
|
|
138
|
+
let defaultValue = defaults[f.name];
|
|
139
|
+
if (defaultValue === undefined) {
|
|
140
|
+
defaultValue = globalDefaultValues(f);
|
|
141
|
+
}
|
|
142
|
+
defaultValue = jsValueToSqlValue(defaultValue, true);
|
|
143
|
+
if (existingField && !f.optional) {
|
|
144
|
+
return `CASE WHEN "${f.name}" IS NULL THEN '${defaultValue}' ELSE "${f.name}" END as "${f.name}"`;
|
|
145
|
+
}
|
|
146
|
+
if (!existingField && !f.optional) {
|
|
147
|
+
return `'${defaultValue}' as "${f.name}"`;
|
|
148
|
+
}
|
|
149
|
+
return `NULL as "${f.name}"`;
|
|
150
|
+
}).join(', ');
|
|
151
|
+
const insertSql = `INSERT INTO "${this.tableName}"(${fieldsInsert}) SELECT ${fieldsSelect} FROM "${tempTableName}"`;
|
|
152
|
+
await this.db.exec(insertSql, []);
|
|
153
|
+
// drop old table
|
|
154
|
+
const dropSql = `DROP TABLE IF EXISTS "${tempTableName}"`;
|
|
155
|
+
await this.db.exec(dropSql, []);
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
tableBuild;
|
|
161
|
+
async initTable(force = false) {
|
|
162
|
+
if (!this.tableBuild || force) {
|
|
163
|
+
this.tableBuild = this.ensureTableIsNewest();
|
|
164
|
+
}
|
|
165
|
+
return this.tableBuild;
|
|
166
|
+
}
|
|
167
|
+
async get(id) {
|
|
168
|
+
let record;
|
|
169
|
+
await this.initTable();
|
|
170
|
+
const sqlRecord = await this.db.get(`SELECT * FROM "${this.tableName}" WHERE ${this.metaData.primaryKeyName} = ?`, [id]);
|
|
171
|
+
record = this.sqlRecordToJsRecord(sqlRecord);
|
|
172
|
+
return record;
|
|
173
|
+
}
|
|
174
|
+
async list(filter = {}, opts = {}) {
|
|
175
|
+
let dataQuery = new data_query_1.DataQuery(this, {
|
|
176
|
+
filter: filter,
|
|
177
|
+
...opts,
|
|
178
|
+
});
|
|
179
|
+
await this.initTable();
|
|
180
|
+
const sqlQuery = (0, data_query_sqlite_1.dataQueryToSqliteQuery)(dataQuery);
|
|
181
|
+
const records = await this.db.all(sqlQuery, []);
|
|
182
|
+
return records.map((r) => this.sqlRecordToJsRecord(r));
|
|
183
|
+
}
|
|
184
|
+
;
|
|
185
|
+
async count(filter = {}) {
|
|
186
|
+
let dataQuery = new data_query_1.DataQuery(this, {
|
|
187
|
+
filter: filter,
|
|
188
|
+
});
|
|
189
|
+
await this.initTable();
|
|
190
|
+
let sqlQuery = (0, data_query_sqlite_1.dataQueryToSqliteQuery)(dataQuery);
|
|
191
|
+
sqlQuery = sqlQuery.replace('SELECT\n *\n', 'SELECT COUNT(*) as cnt\n');
|
|
192
|
+
const cnt = await this.db.get(sqlQuery, []);
|
|
193
|
+
return cnt['cnt'];
|
|
194
|
+
}
|
|
195
|
+
;
|
|
196
|
+
cursor(filter = {}, opts = {}) {
|
|
197
|
+
return (0, data_query_1.dataSourceCursor)(this, filter, opts);
|
|
198
|
+
}
|
|
199
|
+
async findOne(filter = {}, opts = {}) {
|
|
200
|
+
const query = new data_query_1.DataQuery(this, { filter });
|
|
201
|
+
query.pageSize = opts?.enforceUnique ? 2 : 1;
|
|
202
|
+
const records = await query.list();
|
|
203
|
+
if (opts?.enforceUnique && records.length > 1) {
|
|
204
|
+
throw new Error(`Matched more than one record for ${this.tableName} with query ${JSON.stringify(query)}`);
|
|
205
|
+
}
|
|
206
|
+
return records[0];
|
|
207
|
+
}
|
|
208
|
+
async save(record) {
|
|
209
|
+
await this.initTable();
|
|
210
|
+
let newRecord = true;
|
|
211
|
+
const primaryKey = record[this.metaData.primaryKeyName];
|
|
212
|
+
if (primaryKey) {
|
|
213
|
+
const existingRecord = await this.db.get(`SELECT "${this.metaData.primaryKeyName}" FROM "${this.tableName}" WHERE ${this.metaData.primaryKeyName} = ?`, [primaryKey]);
|
|
214
|
+
if (existingRecord) {
|
|
215
|
+
newRecord = false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (newRecord) {
|
|
219
|
+
return await this.insert(record);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
return await this.update(record);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
sqlRecordToJsRecord(record) {
|
|
226
|
+
if (record) {
|
|
227
|
+
for (const field of this.metaData.fields) {
|
|
228
|
+
const fieldValue = record[field.name];
|
|
229
|
+
if (fieldValue === undefined || fieldValue === null) {
|
|
230
|
+
delete record[field.name];
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
record[field.name] =
|
|
234
|
+
sqlValueToJsValue(record[field.name], field.type, field.isArray ?? false);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return record;
|
|
239
|
+
}
|
|
240
|
+
async insert(record) {
|
|
241
|
+
await this.initTable();
|
|
242
|
+
if (!record[this.metaData.primaryKeyName]) {
|
|
243
|
+
// @ts-expect-error - need to figure out how to get typescript to understand what's going on here
|
|
244
|
+
record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
|
|
245
|
+
}
|
|
246
|
+
// validate data
|
|
247
|
+
try {
|
|
248
|
+
this.schema.parse(record);
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
throw new Error(`Validation on insert failed for ${this.tableName}: ${e}`);
|
|
252
|
+
}
|
|
253
|
+
const fields = this.metaData.fields.map(field => `"${field.name}"`).join(', ');
|
|
254
|
+
const values = this.metaData.fields.map(field => jsValueToSqlValue(record[field.name]));
|
|
255
|
+
const placeholders = values.map(v => '?').join(', ');
|
|
256
|
+
const sql = `INSERT INTO "${this.tableName}"(${fields}) VALUES(${placeholders})`;
|
|
257
|
+
await this.db.exec(sql, values);
|
|
258
|
+
return record;
|
|
259
|
+
}
|
|
260
|
+
async update(record) {
|
|
261
|
+
await this.initTable();
|
|
262
|
+
if (!record[this.metaData.primaryKeyName]) {
|
|
263
|
+
// @ts-expect-error - need to figure out how to get typescript to understand what's going on here
|
|
264
|
+
record[this.metaData.primaryKeyName] = (0, utils_1.newid)();
|
|
265
|
+
}
|
|
266
|
+
// validate data
|
|
267
|
+
this.schema.parse(record);
|
|
268
|
+
const primaryKey = record[this.metaData.primaryKeyName];
|
|
269
|
+
const fields = this.metaData.fields.map(field => {
|
|
270
|
+
if (field.name === this.metaData.primaryKeyName)
|
|
271
|
+
return;
|
|
272
|
+
return `"${field.name}" = ?`;
|
|
273
|
+
}).filter(v => v !== undefined).join(',\n');
|
|
274
|
+
const values = this.metaData.fields.map(field => {
|
|
275
|
+
if (field.name === this.metaData.primaryKeyName)
|
|
276
|
+
return;
|
|
277
|
+
return jsValueToSqlValue(record[field.name]);
|
|
278
|
+
}).filter(v => v !== undefined);
|
|
279
|
+
const sql = [
|
|
280
|
+
`UPDATE "${this.tableName}"`,
|
|
281
|
+
`SET ${fields}`,
|
|
282
|
+
`WHERE "${this.metaData.primaryKeyName}" = ?`,
|
|
283
|
+
].join('\n');
|
|
284
|
+
await this.db.exec(sql, [...values, primaryKey]);
|
|
285
|
+
return record;
|
|
286
|
+
}
|
|
287
|
+
async delete(idOrRecord) {
|
|
288
|
+
await this.initTable();
|
|
289
|
+
const primaryKey = typeof idOrRecord === 'string' ? idOrRecord : idOrRecord[this.metaData.primaryKeyName];
|
|
290
|
+
const sql = `DELETE FROM "${this.tableName}" WHERE "${this.metaData.primaryKeyName}" = ?`;
|
|
291
|
+
await this.db.exec(sql, [primaryKey]);
|
|
292
|
+
}
|
|
293
|
+
async dropTableIfExists() {
|
|
294
|
+
const sql = `DROP TABLE IF EXISTS "${this.tableName}"`;
|
|
295
|
+
await this.db.exec(sql, []);
|
|
296
|
+
this.tableBuild = undefined;
|
|
297
|
+
}
|
|
298
|
+
async clearTable() {
|
|
299
|
+
await this.initTable();
|
|
300
|
+
const sql = `DELETE FROM "${this.tableName}"`;
|
|
301
|
+
await this.db.exec(sql, []);
|
|
302
|
+
}
|
|
303
|
+
initRecord(data = {}) {
|
|
304
|
+
const defaults = {};
|
|
305
|
+
for (const field of this.metaData.fields) {
|
|
306
|
+
const zodField = this.schema.shape[field.name];
|
|
307
|
+
const value = zodField.safeParse(data[field.name]);
|
|
308
|
+
if (value.success) {
|
|
309
|
+
// @ts-ignore
|
|
310
|
+
defaults[field.name] = value.data;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return { ...defaults, ...data };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
exports.SQLDataSource = SQLDataSource;
|
|
317
|
+
function jsValueToSqlValue(value, escapeQuote = false) {
|
|
318
|
+
if (value === undefined)
|
|
319
|
+
return null;
|
|
320
|
+
if (value instanceof Date) {
|
|
321
|
+
return value.toISOString();
|
|
322
|
+
}
|
|
323
|
+
if (typeof value === 'object') {
|
|
324
|
+
return (0, serial_json_1.toJSONString)(value);
|
|
325
|
+
}
|
|
326
|
+
if (typeof value === 'boolean') {
|
|
327
|
+
return value ? 1 : 0;
|
|
328
|
+
}
|
|
329
|
+
if (typeof value === 'string' && escapeQuote) {
|
|
330
|
+
return value.replace(/'/g, "''");
|
|
331
|
+
}
|
|
332
|
+
return value;
|
|
333
|
+
}
|
|
334
|
+
function sqlValueToJsValue(value, fieldType, isArray) {
|
|
335
|
+
if (value === null)
|
|
336
|
+
return undefined;
|
|
337
|
+
if (value === undefined)
|
|
338
|
+
return undefined;
|
|
339
|
+
if (isArray) {
|
|
340
|
+
return JSON.parse(value);
|
|
341
|
+
}
|
|
342
|
+
if (fieldType === 'Date') {
|
|
343
|
+
return new Date(value);
|
|
344
|
+
}
|
|
345
|
+
if (fieldType === 'object') {
|
|
346
|
+
return (0, serial_json_1.fromJSONString)(value);
|
|
347
|
+
}
|
|
348
|
+
if (fieldType === 'boolean') {
|
|
349
|
+
return value === 1;
|
|
350
|
+
}
|
|
351
|
+
if (fieldType === 'string') {
|
|
352
|
+
return String(value);
|
|
353
|
+
}
|
|
354
|
+
if (fieldType === 'number') {
|
|
355
|
+
return Number(value);
|
|
356
|
+
}
|
|
357
|
+
return value;
|
|
358
|
+
}
|
|
359
|
+
function globalDefaultValues(field) {
|
|
360
|
+
const fieldType = field.type;
|
|
361
|
+
const isArray = field.isArray ?? false;
|
|
362
|
+
if (isArray) {
|
|
363
|
+
return [];
|
|
364
|
+
}
|
|
365
|
+
switch (fieldType) {
|
|
366
|
+
case 'Date':
|
|
367
|
+
return new Date(0);
|
|
368
|
+
case 'object':
|
|
369
|
+
return {};
|
|
370
|
+
case 'boolean':
|
|
371
|
+
return false;
|
|
372
|
+
case 'string':
|
|
373
|
+
return '';
|
|
374
|
+
case 'number':
|
|
375
|
+
return 0;
|
|
376
|
+
default:
|
|
377
|
+
return '';
|
|
378
|
+
}
|
|
379
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|