@framers/sql-storage-adapter 0.7.2 → 0.7.3
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 +20 -0
- package/dist/adapters/electron/preload.cjs +289 -0
- package/dist/adapters/electron/renderer.d.ts +9 -0
- package/dist/adapters/electron/renderer.d.ts.map +1 -0
- package/dist/adapters/electron/renderer.js +8 -0
- package/dist/adapters/electron/renderer.js.map +1 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
- package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
- package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
- package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
- package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
- package/dist/cjs/adapters/electron/index.d.ts +74 -0
- package/dist/cjs/adapters/electron/index.js +86 -0
- package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
- package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
- package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/ipc/index.js +38 -0
- package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
- package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
- package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
- package/dist/cjs/adapters/electron/ipc/types.js +15 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
- package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/migration/index.js +29 -0
- package/dist/cjs/adapters/electron/preload.d.ts +126 -0
- package/dist/cjs/adapters/electron/preload.js +233 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
- package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/recovery/index.js +34 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
- package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
- package/dist/cjs/adapters/electron/renderer.js +33 -0
- package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/window/index.js +29 -0
- package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
- package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
- package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
- package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
- package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
- package/dist/cjs/adapters/postgresAdapter.js +889 -0
- package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
- package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
- package/dist/cjs/adapters/supabase.d.ts +58 -0
- package/dist/cjs/adapters/supabase.js +401 -0
- package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
- package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
- package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
- package/dist/cjs/core/contracts/blobCodec.js +15 -0
- package/dist/cjs/core/contracts/context.d.ts +221 -0
- package/dist/cjs/core/contracts/context.js +15 -0
- package/dist/cjs/core/contracts/dialect.d.ts +154 -0
- package/dist/cjs/core/contracts/dialect.js +15 -0
- package/dist/cjs/core/contracts/events.d.ts +225 -0
- package/dist/cjs/core/contracts/events.js +15 -0
- package/dist/cjs/core/contracts/exporter.d.ts +13 -0
- package/dist/cjs/core/contracts/exporter.js +15 -0
- package/dist/cjs/core/contracts/extensions.d.ts +73 -0
- package/dist/cjs/core/contracts/extensions.js +15 -0
- package/dist/cjs/core/contracts/features.d.ts +25 -0
- package/dist/cjs/core/contracts/features.js +61 -0
- package/dist/cjs/core/contracts/fts.d.ts +66 -0
- package/dist/cjs/core/contracts/fts.js +15 -0
- package/dist/cjs/core/contracts/hooks.d.ts +481 -0
- package/dist/cjs/core/contracts/hooks.js +140 -0
- package/dist/cjs/core/contracts/index.d.ts +260 -0
- package/dist/cjs/core/contracts/index.js +41 -0
- package/dist/cjs/core/contracts/limitations.d.ts +46 -0
- package/dist/cjs/core/contracts/limitations.js +218 -0
- package/dist/cjs/core/contracts/performance.d.ts +308 -0
- package/dist/cjs/core/contracts/performance.js +144 -0
- package/dist/cjs/core/database.d.ts +220 -0
- package/dist/cjs/core/database.js +136 -0
- package/dist/cjs/core/portable.d.ts +23 -0
- package/dist/cjs/core/portable.js +66 -0
- package/dist/cjs/core/resolver.d.ts +77 -0
- package/dist/cjs/core/resolver.js +235 -0
- package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
- package/dist/cjs/dialects/PostgresDialect.js +143 -0
- package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
- package/dist/cjs/dialects/SqliteDialect.js +142 -0
- package/dist/cjs/dialects/shared.d.ts +17 -0
- package/dist/cjs/dialects/shared.js +90 -0
- package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
- package/dist/cjs/exporters/PostgresExporter.js +61 -0
- package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
- package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
- package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
- package/dist/cjs/features/backup/cloudBackup.js +209 -0
- package/dist/cjs/features/kv/idb.d.ts +79 -0
- package/dist/cjs/features/kv/idb.js +32 -0
- package/dist/cjs/features/kv/index.d.ts +14 -0
- package/dist/cjs/features/kv/index.js +40 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
- package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
- package/dist/cjs/features/kv/keyValueStore.js +67 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
- package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
- package/dist/cjs/features/kv/valueCodec.js +426 -0
- package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
- package/dist/cjs/features/migrations/dataExport.js +194 -0
- package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
- package/dist/cjs/features/migrations/dataImport.js +300 -0
- package/dist/cjs/features/migrations/migration.d.ts +89 -0
- package/dist/cjs/features/migrations/migration.js +187 -0
- package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
- package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
- package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
- package/dist/cjs/features/sync/conflicts/index.js +21 -0
- package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
- package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
- package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
- package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
- package/dist/cjs/features/sync/devices/index.d.ts +10 -0
- package/dist/cjs/features/sync/devices/index.js +21 -0
- package/dist/cjs/features/sync/index.d.ts +37 -0
- package/dist/cjs/features/sync/index.js +111 -0
- package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
- package/dist/cjs/features/sync/protocol/index.js +23 -0
- package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
- package/dist/cjs/features/sync/protocol/messages.js +215 -0
- package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
- package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
- package/dist/cjs/features/sync/syncManager.d.ts +348 -0
- package/dist/cjs/features/sync/syncManager.js +455 -0
- package/dist/cjs/features/sync/tables/index.d.ts +10 -0
- package/dist/cjs/features/sync/tables/index.js +21 -0
- package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
- package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
- package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
- package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
- package/dist/cjs/features/sync/transport/index.d.ts +12 -0
- package/dist/cjs/features/sync/transport/index.js +25 -0
- package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
- package/dist/cjs/features/sync/transport/transport.js +163 -0
- package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
- package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
- package/dist/cjs/fts/PostgresFts.d.ts +29 -0
- package/dist/cjs/fts/PostgresFts.js +77 -0
- package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
- package/dist/cjs/fts/SqliteFts5.js +58 -0
- package/dist/cjs/index.d.ts +30 -0
- package/dist/cjs/index.js +101 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/shared/connectionGate.d.ts +94 -0
- package/dist/cjs/shared/connectionGate.js +77 -0
- package/dist/cjs/shared/errors.d.ts +23 -0
- package/dist/cjs/shared/errors.js +45 -0
- package/dist/cjs/shared/logger.d.ts +26 -0
- package/dist/cjs/shared/logger.js +40 -0
- package/dist/cjs/shared/parameterUtils.d.ts +16 -0
- package/dist/cjs/shared/parameterUtils.js +59 -0
- package/dist/cjs/shared/postgresTarget.d.ts +11 -0
- package/dist/cjs/shared/postgresTarget.js +30 -0
- package/dist/cjs/shared/segment.d.ts +43 -0
- package/dist/cjs/shared/segment.js +63 -0
- package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
- package/dist/cjs/shared/serializedTransaction.js +74 -0
- package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
- package/dist/cjs/shared/splitSqlStatements.js +163 -0
- package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
- package/dist/cjs/shared/sqlPlaceholders.js +263 -0
- package/dist/cjs/types/index.d.ts +29 -0
- package/dist/cjs/types/index.js +33 -0
- package/dist/core/portable.d.ts +23 -0
- package/dist/core/portable.d.ts.map +1 -0
- package/dist/core/portable.js +23 -0
- package/dist/core/portable.js.map +1 -0
- package/package.json +139 -24
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var valueCodec_exports = {};
|
|
19
|
+
__export(valueCodec_exports, {
|
|
20
|
+
decodeValue: () => decodeValue,
|
|
21
|
+
encodeValue: () => encodeValue
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(valueCodec_exports);
|
|
24
|
+
const FORMAT = 1;
|
|
25
|
+
const ERROR_CONSTRUCTORS = {
|
|
26
|
+
EvalError,
|
|
27
|
+
RangeError,
|
|
28
|
+
ReferenceError,
|
|
29
|
+
SyntaxError,
|
|
30
|
+
TypeError,
|
|
31
|
+
URIError
|
|
32
|
+
};
|
|
33
|
+
const TYPED_ARRAY_NAMES = /* @__PURE__ */ new Set([
|
|
34
|
+
"Int8Array",
|
|
35
|
+
"Uint8Array",
|
|
36
|
+
"Uint8ClampedArray",
|
|
37
|
+
"Int16Array",
|
|
38
|
+
"Uint16Array",
|
|
39
|
+
"Int32Array",
|
|
40
|
+
"Uint32Array",
|
|
41
|
+
"Float16Array",
|
|
42
|
+
"Float32Array",
|
|
43
|
+
"Float64Array",
|
|
44
|
+
"BigInt64Array",
|
|
45
|
+
"BigUint64Array"
|
|
46
|
+
]);
|
|
47
|
+
const REFUSED_TAG = /^\[object (?:Promise|WeakMap|WeakSet|WeakRef|FinalizationRegistry|SharedArrayBuffer|Symbol|Arguments|Generator|AsyncGenerator|[A-Za-z ]+ Iterator|Blob|File|FileList|ImageData|ImageBitmap|OffscreenCanvas|CryptoKey|MessagePort|ReadableStream|WritableStream|TransformStream|VideoFrame|AudioData|RTCCertificate|FileSystemHandle|FileSystemFileHandle|FileSystemDirectoryHandle|GPUCompilationMessage|global|Window|Intl\.[A-Za-z]+)\]$/;
|
|
48
|
+
const getter = (owner, name) => {
|
|
49
|
+
const found = Object.getOwnPropertyDescriptor(owner, name)?.get;
|
|
50
|
+
if (!found)
|
|
51
|
+
throw new Error(`valueCodec: ${String(name)} has no getter`);
|
|
52
|
+
return found;
|
|
53
|
+
};
|
|
54
|
+
const MAP_SIZE = getter(Map.prototype, "size");
|
|
55
|
+
const SET_SIZE = getter(Set.prototype, "size");
|
|
56
|
+
const ARRAY_BUFFER_BYTE_LENGTH = getter(ArrayBuffer.prototype, "byteLength");
|
|
57
|
+
const DATA_VIEW_BYTE_LENGTH = getter(DataView.prototype, "byteLength");
|
|
58
|
+
const REGEXP_SOURCE = getter(RegExp.prototype, "source");
|
|
59
|
+
const REGEXP_FLAGS = getter(RegExp.prototype, "flags");
|
|
60
|
+
const TYPED_ARRAY_NAME = getter(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag);
|
|
61
|
+
const holds = (call) => {
|
|
62
|
+
try {
|
|
63
|
+
call();
|
|
64
|
+
return true;
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const cloneError = (what) => {
|
|
70
|
+
const message = `${what} could not be cloned.`;
|
|
71
|
+
const DomException = globalThis.DOMException;
|
|
72
|
+
if (typeof DomException === "function") {
|
|
73
|
+
return new DomException(message, "DataCloneError");
|
|
74
|
+
}
|
|
75
|
+
const error = new Error(message);
|
|
76
|
+
error.name = "DataCloneError";
|
|
77
|
+
return error;
|
|
78
|
+
};
|
|
79
|
+
const BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
80
|
+
const BASE64_VALUES = new Map([...BASE64].map((char, index) => [char, index]));
|
|
81
|
+
const toBase64 = (bytes) => {
|
|
82
|
+
const parts = [];
|
|
83
|
+
let i = 0;
|
|
84
|
+
for (; i + 2 < bytes.length; i += 3) {
|
|
85
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
86
|
+
parts.push(BASE64[n >> 18 & 63] + BASE64[n >> 12 & 63] + BASE64[n >> 6 & 63] + BASE64[n & 63]);
|
|
87
|
+
}
|
|
88
|
+
const rest = bytes.length - i;
|
|
89
|
+
if (rest === 1) {
|
|
90
|
+
const n = bytes[i] << 16;
|
|
91
|
+
parts.push(`${BASE64[n >> 18 & 63]}${BASE64[n >> 12 & 63]}==`);
|
|
92
|
+
} else if (rest === 2) {
|
|
93
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8;
|
|
94
|
+
parts.push(`${BASE64[n >> 18 & 63]}${BASE64[n >> 12 & 63]}${BASE64[n >> 6 & 63]}=`);
|
|
95
|
+
}
|
|
96
|
+
return parts.join("");
|
|
97
|
+
};
|
|
98
|
+
const fromBase64 = (text) => {
|
|
99
|
+
const digits = text.replace(/=+$/, "");
|
|
100
|
+
const bytes = new Uint8Array(Math.floor(digits.length * 3 / 4));
|
|
101
|
+
let bits = 0;
|
|
102
|
+
let pending = 0;
|
|
103
|
+
let at = 0;
|
|
104
|
+
for (const char of digits) {
|
|
105
|
+
const value = BASE64_VALUES.get(char);
|
|
106
|
+
if (value === void 0)
|
|
107
|
+
throw new Error("valueCodec: the stored bytes are not base64.");
|
|
108
|
+
pending = (pending << 6 | value) & 16777215;
|
|
109
|
+
bits += 6;
|
|
110
|
+
if (bits >= 8) {
|
|
111
|
+
bits -= 8;
|
|
112
|
+
bytes[at] = pending >> bits & 255;
|
|
113
|
+
at += 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return bytes;
|
|
117
|
+
};
|
|
118
|
+
const numberNode = (value) => {
|
|
119
|
+
if (Number.isNaN(value))
|
|
120
|
+
return ["n", "NaN"];
|
|
121
|
+
if (value === Infinity)
|
|
122
|
+
return ["n", "Infinity"];
|
|
123
|
+
if (value === -Infinity)
|
|
124
|
+
return ["n", "-Infinity"];
|
|
125
|
+
if (Object.is(value, -0))
|
|
126
|
+
return ["n", "-0"];
|
|
127
|
+
return value;
|
|
128
|
+
};
|
|
129
|
+
function encodeValue(value) {
|
|
130
|
+
const ids = /* @__PURE__ */ new Map();
|
|
131
|
+
const encode = (input) => {
|
|
132
|
+
switch (typeof input) {
|
|
133
|
+
case "string":
|
|
134
|
+
case "boolean":
|
|
135
|
+
return input;
|
|
136
|
+
case "number":
|
|
137
|
+
return numberNode(input);
|
|
138
|
+
case "undefined":
|
|
139
|
+
return ["u"];
|
|
140
|
+
case "bigint":
|
|
141
|
+
return ["b", input.toString()];
|
|
142
|
+
case "symbol":
|
|
143
|
+
throw cloneError("A symbol");
|
|
144
|
+
case "function":
|
|
145
|
+
throw cloneError("A function");
|
|
146
|
+
}
|
|
147
|
+
if (input === null)
|
|
148
|
+
return null;
|
|
149
|
+
const object = input;
|
|
150
|
+
const seen = ids.get(object);
|
|
151
|
+
if (seen !== void 0)
|
|
152
|
+
return ["r", seen];
|
|
153
|
+
ids.set(object, ids.size);
|
|
154
|
+
return encodeObject(object);
|
|
155
|
+
};
|
|
156
|
+
const properties = (object) => {
|
|
157
|
+
const entries = [];
|
|
158
|
+
for (const key of Object.keys(object)) {
|
|
159
|
+
entries.push(key, encode(object[key]));
|
|
160
|
+
}
|
|
161
|
+
return entries;
|
|
162
|
+
};
|
|
163
|
+
const encodeObject = (object) => {
|
|
164
|
+
if (Array.isArray(object)) {
|
|
165
|
+
return ["a", object.length, properties(object)];
|
|
166
|
+
}
|
|
167
|
+
if (holds(() => Date.prototype.getTime.call(object))) {
|
|
168
|
+
return ["D", numberNode(Date.prototype.getTime.call(object))];
|
|
169
|
+
}
|
|
170
|
+
if (object !== RegExp.prototype && holds(() => REGEXP_SOURCE.call(object))) {
|
|
171
|
+
return ["R", REGEXP_SOURCE.call(object), REGEXP_FLAGS.call(object)];
|
|
172
|
+
}
|
|
173
|
+
if (holds(() => MAP_SIZE.call(object))) {
|
|
174
|
+
const entries = [];
|
|
175
|
+
Map.prototype.forEach.call(object, (entryValue, entryKey) => {
|
|
176
|
+
entries.push(encode(entryKey), encode(entryValue));
|
|
177
|
+
});
|
|
178
|
+
return ["M", entries];
|
|
179
|
+
}
|
|
180
|
+
if (holds(() => SET_SIZE.call(object))) {
|
|
181
|
+
const members = [];
|
|
182
|
+
Set.prototype.forEach.call(object, (member) => {
|
|
183
|
+
members.push(encode(member));
|
|
184
|
+
});
|
|
185
|
+
return ["S", members];
|
|
186
|
+
}
|
|
187
|
+
if (holds(() => ARRAY_BUFFER_BYTE_LENGTH.call(object))) {
|
|
188
|
+
if (object.detached === true)
|
|
189
|
+
throw cloneError("A detached ArrayBuffer");
|
|
190
|
+
return ["B", toBase64(new Uint8Array(object))];
|
|
191
|
+
}
|
|
192
|
+
if (ArrayBuffer.isView(object)) {
|
|
193
|
+
if (holds(() => DATA_VIEW_BYTE_LENGTH.call(object))) {
|
|
194
|
+
const view = object;
|
|
195
|
+
return ["V", encode(view.buffer), view.byteOffset, view.byteLength];
|
|
196
|
+
}
|
|
197
|
+
const name = TYPED_ARRAY_NAME.call(object);
|
|
198
|
+
if (typeof name === "string" && TYPED_ARRAY_NAMES.has(name)) {
|
|
199
|
+
const view = object;
|
|
200
|
+
return ["T", name, encode(view.buffer), view.byteOffset, view.length];
|
|
201
|
+
}
|
|
202
|
+
throw cloneError("An ArrayBuffer view");
|
|
203
|
+
}
|
|
204
|
+
if (holds(() => Number.prototype.valueOf.call(object))) {
|
|
205
|
+
return ["N", numberNode(Number.prototype.valueOf.call(object))];
|
|
206
|
+
}
|
|
207
|
+
if (holds(() => String.prototype.valueOf.call(object))) {
|
|
208
|
+
return ["Z", String.prototype.valueOf.call(object)];
|
|
209
|
+
}
|
|
210
|
+
if (holds(() => Boolean.prototype.valueOf.call(object))) {
|
|
211
|
+
return ["Q", Boolean.prototype.valueOf.call(object)];
|
|
212
|
+
}
|
|
213
|
+
if (typeof BigInt === "function" && holds(() => BigInt.prototype.valueOf.call(object))) {
|
|
214
|
+
return ["G", BigInt.prototype.valueOf.call(object).toString()];
|
|
215
|
+
}
|
|
216
|
+
if (holds(() => Symbol.prototype.valueOf.call(object))) {
|
|
217
|
+
throw cloneError("A Symbol object");
|
|
218
|
+
}
|
|
219
|
+
const tag = Object.prototype.toString.call(object);
|
|
220
|
+
if (isError(object, tag)) {
|
|
221
|
+
return encodeError(object);
|
|
222
|
+
}
|
|
223
|
+
if (REFUSED_TAG.test(tag)) {
|
|
224
|
+
throw cloneError(tag.slice(8, -1));
|
|
225
|
+
}
|
|
226
|
+
return ["o", properties(object)];
|
|
227
|
+
};
|
|
228
|
+
const encodeError = (error) => {
|
|
229
|
+
const name = String(error.name);
|
|
230
|
+
const prototypeName = Object.prototype.hasOwnProperty.call(ERROR_CONSTRUCTORS, name) ? name : "Error";
|
|
231
|
+
const messageDescriptor = Object.getOwnPropertyDescriptor(error, "message");
|
|
232
|
+
const message = messageDescriptor && "value" in messageDescriptor ? String(messageDescriptor.value) : null;
|
|
233
|
+
const stack = error.stack;
|
|
234
|
+
const node = ["E", prototypeName, message, typeof stack === "string" ? stack : null];
|
|
235
|
+
const causeDescriptor = Object.getOwnPropertyDescriptor(error, "cause");
|
|
236
|
+
if (causeDescriptor && "value" in causeDescriptor) {
|
|
237
|
+
node.push(encode(causeDescriptor.value));
|
|
238
|
+
}
|
|
239
|
+
return node;
|
|
240
|
+
};
|
|
241
|
+
return JSON.stringify([FORMAT, encode(value)]);
|
|
242
|
+
}
|
|
243
|
+
const isError = (object, tag) => {
|
|
244
|
+
const errorIs = Error.isError;
|
|
245
|
+
return typeof errorIs === "function" ? errorIs(object) : tag === "[object Error]";
|
|
246
|
+
};
|
|
247
|
+
const defineOwn = (target, key, value) => {
|
|
248
|
+
Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
|
|
249
|
+
};
|
|
250
|
+
function decodeValue(text) {
|
|
251
|
+
const parsed = JSON.parse(text);
|
|
252
|
+
if (!Array.isArray(parsed) || parsed.length !== 2 || parsed[0] !== FORMAT) {
|
|
253
|
+
throw new Error("valueCodec: the stored value is not one the key-value store wrote.");
|
|
254
|
+
}
|
|
255
|
+
const objects = [];
|
|
256
|
+
const malformed = () => new Error("valueCodec: the stored value is malformed.");
|
|
257
|
+
const reserve = () => {
|
|
258
|
+
objects.push(void 0);
|
|
259
|
+
return objects.length - 1;
|
|
260
|
+
};
|
|
261
|
+
const register = (object) => {
|
|
262
|
+
objects.push(object);
|
|
263
|
+
return object;
|
|
264
|
+
};
|
|
265
|
+
const decodeNumber = (node) => {
|
|
266
|
+
const decoded = decode(node);
|
|
267
|
+
if (typeof decoded !== "number")
|
|
268
|
+
throw malformed();
|
|
269
|
+
return decoded;
|
|
270
|
+
};
|
|
271
|
+
const decodeProperties = (target, entries) => {
|
|
272
|
+
if (!Array.isArray(entries) || entries.length % 2 !== 0)
|
|
273
|
+
throw malformed();
|
|
274
|
+
for (let i = 0; i < entries.length; i += 2) {
|
|
275
|
+
const key = entries[i];
|
|
276
|
+
if (typeof key !== "string")
|
|
277
|
+
throw malformed();
|
|
278
|
+
defineOwn(target, key, decode(entries[i + 1]));
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
const decode = (node) => {
|
|
282
|
+
if (node === null || typeof node === "string" || typeof node === "number" || typeof node === "boolean") {
|
|
283
|
+
return node;
|
|
284
|
+
}
|
|
285
|
+
if (!Array.isArray(node) || typeof node[0] !== "string")
|
|
286
|
+
throw malformed();
|
|
287
|
+
switch (node[0]) {
|
|
288
|
+
case "u":
|
|
289
|
+
return void 0;
|
|
290
|
+
case "n":
|
|
291
|
+
switch (node[1]) {
|
|
292
|
+
case "NaN":
|
|
293
|
+
return NaN;
|
|
294
|
+
case "Infinity":
|
|
295
|
+
return Infinity;
|
|
296
|
+
case "-Infinity":
|
|
297
|
+
return -Infinity;
|
|
298
|
+
case "-0":
|
|
299
|
+
return -0;
|
|
300
|
+
default:
|
|
301
|
+
throw malformed();
|
|
302
|
+
}
|
|
303
|
+
case "b":
|
|
304
|
+
return BigInt(String(node[1]));
|
|
305
|
+
case "r": {
|
|
306
|
+
const id = node[1];
|
|
307
|
+
if (typeof id !== "number" || id < 0 || id >= objects.length)
|
|
308
|
+
throw malformed();
|
|
309
|
+
return objects[id];
|
|
310
|
+
}
|
|
311
|
+
case "o": {
|
|
312
|
+
const object = register({});
|
|
313
|
+
decodeProperties(object, node[1]);
|
|
314
|
+
return object;
|
|
315
|
+
}
|
|
316
|
+
case "a": {
|
|
317
|
+
if (typeof node[1] !== "number")
|
|
318
|
+
throw malformed();
|
|
319
|
+
const array = register(new Array(node[1]));
|
|
320
|
+
decodeProperties(array, node[2]);
|
|
321
|
+
return array;
|
|
322
|
+
}
|
|
323
|
+
case "D": {
|
|
324
|
+
const id = reserve();
|
|
325
|
+
const date = new Date(decodeNumber(node[1]));
|
|
326
|
+
objects[id] = date;
|
|
327
|
+
return date;
|
|
328
|
+
}
|
|
329
|
+
case "R":
|
|
330
|
+
return register(new RegExp(String(node[1]), String(node[2])));
|
|
331
|
+
case "M": {
|
|
332
|
+
const map = register(/* @__PURE__ */ new Map());
|
|
333
|
+
const entries = node[1];
|
|
334
|
+
if (!Array.isArray(entries) || entries.length % 2 !== 0)
|
|
335
|
+
throw malformed();
|
|
336
|
+
for (let i = 0; i < entries.length; i += 2) {
|
|
337
|
+
const key = decode(entries[i]);
|
|
338
|
+
map.set(key, decode(entries[i + 1]));
|
|
339
|
+
}
|
|
340
|
+
return map;
|
|
341
|
+
}
|
|
342
|
+
case "S": {
|
|
343
|
+
const set = register(/* @__PURE__ */ new Set());
|
|
344
|
+
const members = node[1];
|
|
345
|
+
if (!Array.isArray(members))
|
|
346
|
+
throw malformed();
|
|
347
|
+
for (const member of members)
|
|
348
|
+
set.add(decode(member));
|
|
349
|
+
return set;
|
|
350
|
+
}
|
|
351
|
+
case "B": {
|
|
352
|
+
const bytes = fromBase64(String(node[1]));
|
|
353
|
+
return register(bytes.buffer);
|
|
354
|
+
}
|
|
355
|
+
case "V": {
|
|
356
|
+
const id = reserve();
|
|
357
|
+
const buffer = decode(node[1]);
|
|
358
|
+
if (!(buffer instanceof ArrayBuffer))
|
|
359
|
+
throw malformed();
|
|
360
|
+
const view = new DataView(buffer, Number(node[2]), Number(node[3]));
|
|
361
|
+
objects[id] = view;
|
|
362
|
+
return view;
|
|
363
|
+
}
|
|
364
|
+
case "T": {
|
|
365
|
+
const name = String(node[1]);
|
|
366
|
+
const Constructor = globalThis[name];
|
|
367
|
+
if (!TYPED_ARRAY_NAMES.has(name) || typeof Constructor !== "function")
|
|
368
|
+
throw malformed();
|
|
369
|
+
const id = reserve();
|
|
370
|
+
const buffer = decode(node[2]);
|
|
371
|
+
if (!(buffer instanceof ArrayBuffer))
|
|
372
|
+
throw malformed();
|
|
373
|
+
const view = new Constructor(buffer, Number(node[3]), Number(node[4]));
|
|
374
|
+
objects[id] = view;
|
|
375
|
+
return view;
|
|
376
|
+
}
|
|
377
|
+
case "N": {
|
|
378
|
+
const id = reserve();
|
|
379
|
+
const boxed = new Number(decodeNumber(node[1]));
|
|
380
|
+
objects[id] = boxed;
|
|
381
|
+
return boxed;
|
|
382
|
+
}
|
|
383
|
+
case "Z":
|
|
384
|
+
return register(new String(String(node[1])));
|
|
385
|
+
case "Q":
|
|
386
|
+
return register(new Boolean(node[1] === true));
|
|
387
|
+
case "G":
|
|
388
|
+
return register(Object(BigInt(String(node[1]))));
|
|
389
|
+
case "E":
|
|
390
|
+
return decodeError(node);
|
|
391
|
+
default:
|
|
392
|
+
throw malformed();
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
const decodeError = (node) => {
|
|
396
|
+
const name = String(node[1]);
|
|
397
|
+
const Constructor = Object.prototype.hasOwnProperty.call(ERROR_CONSTRUCTORS, name) ? ERROR_CONSTRUCTORS[name] : Error;
|
|
398
|
+
const message = node[2];
|
|
399
|
+
const error = typeof message === "string" ? new Constructor(message) : new Constructor();
|
|
400
|
+
register(error);
|
|
401
|
+
const stack = node[3];
|
|
402
|
+
try {
|
|
403
|
+
if (typeof stack === "string") {
|
|
404
|
+
Object.defineProperty(error, "stack", { value: stack, writable: true, enumerable: false, configurable: true });
|
|
405
|
+
} else {
|
|
406
|
+
delete error.stack;
|
|
407
|
+
}
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
if (node.length > 4) {
|
|
411
|
+
Object.defineProperty(error, "cause", {
|
|
412
|
+
value: decode(node[4]),
|
|
413
|
+
writable: true,
|
|
414
|
+
enumerable: false,
|
|
415
|
+
configurable: true
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
return error;
|
|
419
|
+
};
|
|
420
|
+
return decode(parsed[1]);
|
|
421
|
+
}
|
|
422
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
423
|
+
0 && (module.exports = {
|
|
424
|
+
decodeValue,
|
|
425
|
+
encodeValue
|
|
426
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data export utilities for cross-adapter migration and backup.
|
|
3
|
+
* Supports exporting data to portable formats (JSON, SQL, CSV).
|
|
4
|
+
*/
|
|
5
|
+
import type { StorageAdapter } from '../../core/contracts/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Export format types.
|
|
8
|
+
*/
|
|
9
|
+
export type ExportFormat = 'json' | 'sql' | 'csv';
|
|
10
|
+
/**
|
|
11
|
+
* Options for data export.
|
|
12
|
+
*/
|
|
13
|
+
export interface DataExportOptions {
|
|
14
|
+
/** Tables to export (all if not specified) */
|
|
15
|
+
tables?: string[];
|
|
16
|
+
/** Include schema/DDL statements */
|
|
17
|
+
includeSchema?: boolean;
|
|
18
|
+
/** Format for export */
|
|
19
|
+
format?: ExportFormat;
|
|
20
|
+
/** Batch size for large exports */
|
|
21
|
+
batchSize?: number;
|
|
22
|
+
/** Whether to pretty-print JSON */
|
|
23
|
+
pretty?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Exported data structure.
|
|
27
|
+
*/
|
|
28
|
+
export interface ExportedData {
|
|
29
|
+
version: string;
|
|
30
|
+
exportedAt: string;
|
|
31
|
+
adapter: string;
|
|
32
|
+
schema?: TableSchema[];
|
|
33
|
+
data: Record<string, unknown[]>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Table schema information.
|
|
37
|
+
*/
|
|
38
|
+
export interface TableSchema {
|
|
39
|
+
name: string;
|
|
40
|
+
columns: ColumnInfo[];
|
|
41
|
+
primaryKeys?: string[];
|
|
42
|
+
indexes?: IndexInfo[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Column information.
|
|
46
|
+
*/
|
|
47
|
+
export interface ColumnInfo {
|
|
48
|
+
name: string;
|
|
49
|
+
type: string;
|
|
50
|
+
nullable?: boolean;
|
|
51
|
+
defaultValue?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Index information.
|
|
55
|
+
*/
|
|
56
|
+
export interface IndexInfo {
|
|
57
|
+
name: string;
|
|
58
|
+
columns: string[];
|
|
59
|
+
unique?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Export data from an adapter to a portable format.
|
|
63
|
+
*/
|
|
64
|
+
export declare function exportData(adapter: StorageAdapter, options?: DataExportOptions): Promise<ExportedData>;
|
|
65
|
+
/**
|
|
66
|
+
* Export data as JSON string.
|
|
67
|
+
*/
|
|
68
|
+
export declare function exportAsJSON(adapter: StorageAdapter, options?: DataExportOptions): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Export data as SQL statements.
|
|
71
|
+
*/
|
|
72
|
+
export declare function exportAsSQL(adapter: StorageAdapter, options?: DataExportOptions): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* Export data as CSV (one file per table).
|
|
75
|
+
*/
|
|
76
|
+
export declare function exportAsCSV(adapter: StorageAdapter, options?: DataExportOptions): Promise<Record<string, string>>;
|
|
77
|
+
//# sourceMappingURL=dataExport.d.ts.map
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var dataExport_exports = {};
|
|
19
|
+
__export(dataExport_exports, {
|
|
20
|
+
exportAsCSV: () => exportAsCSV,
|
|
21
|
+
exportAsJSON: () => exportAsJSON,
|
|
22
|
+
exportAsSQL: () => exportAsSQL,
|
|
23
|
+
exportData: () => exportData
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(dataExport_exports);
|
|
26
|
+
async function exportData(adapter, options = {}) {
|
|
27
|
+
const { tables, includeSchema = true, batchSize = 1e3 } = options;
|
|
28
|
+
const exportedData = {
|
|
29
|
+
version: "1.0.0",
|
|
30
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31
|
+
adapter: "sql-storage-adapter",
|
|
32
|
+
data: {}
|
|
33
|
+
};
|
|
34
|
+
const tablesToExport = tables || await getTables(adapter);
|
|
35
|
+
if (includeSchema) {
|
|
36
|
+
exportedData.schema = await Promise.all(tablesToExport.map((table) => getTableSchema(adapter, table)));
|
|
37
|
+
}
|
|
38
|
+
for (const table of tablesToExport) {
|
|
39
|
+
const rows = [];
|
|
40
|
+
let offset = 0;
|
|
41
|
+
let batch;
|
|
42
|
+
do {
|
|
43
|
+
batch = await adapter.all(`SELECT * FROM ${escapeIdentifier(table)} LIMIT ${batchSize} OFFSET ${offset}`);
|
|
44
|
+
rows.push(...batch);
|
|
45
|
+
offset += batchSize;
|
|
46
|
+
} while (batch.length === batchSize);
|
|
47
|
+
exportedData.data[table] = rows;
|
|
48
|
+
}
|
|
49
|
+
return exportedData;
|
|
50
|
+
}
|
|
51
|
+
async function exportAsJSON(adapter, options = {}) {
|
|
52
|
+
const data = await exportData(adapter, options);
|
|
53
|
+
return JSON.stringify(data, null, options.pretty ? 2 : 0);
|
|
54
|
+
}
|
|
55
|
+
async function exportAsSQL(adapter, options = {}) {
|
|
56
|
+
const data = await exportData(adapter, options);
|
|
57
|
+
const lines = [];
|
|
58
|
+
lines.push("-- SQL Export from sql-storage-adapter");
|
|
59
|
+
lines.push(`-- Generated at: ${data.exportedAt}`);
|
|
60
|
+
lines.push("");
|
|
61
|
+
if (data.schema) {
|
|
62
|
+
for (const table of data.schema) {
|
|
63
|
+
lines.push(`-- Table: ${table.name}`);
|
|
64
|
+
lines.push(generateCreateTableSQL(table));
|
|
65
|
+
lines.push("");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const [tableName, rows] of Object.entries(data.data)) {
|
|
69
|
+
if (rows.length === 0)
|
|
70
|
+
continue;
|
|
71
|
+
lines.push(`-- Data for table: ${tableName}`);
|
|
72
|
+
for (const row of rows) {
|
|
73
|
+
lines.push(generateInsertSQL(tableName, row));
|
|
74
|
+
}
|
|
75
|
+
lines.push("");
|
|
76
|
+
}
|
|
77
|
+
return lines.join("\n");
|
|
78
|
+
}
|
|
79
|
+
async function exportAsCSV(adapter, options = {}) {
|
|
80
|
+
const data = await exportData(adapter, options);
|
|
81
|
+
const csvFiles = {};
|
|
82
|
+
for (const [tableName, rows] of Object.entries(data.data)) {
|
|
83
|
+
if (rows.length === 0) {
|
|
84
|
+
csvFiles[tableName] = "";
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const firstRow = rows[0];
|
|
88
|
+
const headers = Object.keys(firstRow);
|
|
89
|
+
const lines = [];
|
|
90
|
+
lines.push(headers.map(escapeCSVValue).join(","));
|
|
91
|
+
for (const row of rows) {
|
|
92
|
+
const values = headers.map((header) => escapeCSVValue(String(row[header] ?? "")));
|
|
93
|
+
lines.push(values.join(","));
|
|
94
|
+
}
|
|
95
|
+
csvFiles[tableName] = lines.join("\n");
|
|
96
|
+
}
|
|
97
|
+
return csvFiles;
|
|
98
|
+
}
|
|
99
|
+
async function getTables(adapter) {
|
|
100
|
+
try {
|
|
101
|
+
const rows = await adapter.all(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'`);
|
|
102
|
+
return rows.map((r) => r.name);
|
|
103
|
+
} catch {
|
|
104
|
+
try {
|
|
105
|
+
const rows = await adapter.all(`SELECT tablename AS name FROM pg_tables WHERE schemaname = current_schema() ORDER BY tablename`);
|
|
106
|
+
return rows.map((r) => r.name);
|
|
107
|
+
} catch {
|
|
108
|
+
throw new Error("Unable to retrieve table list from adapter");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function getTableSchema(adapter, table) {
|
|
113
|
+
try {
|
|
114
|
+
const columns = await adapter.all(`PRAGMA table_info(${escapeIdentifier(table)})`);
|
|
115
|
+
return {
|
|
116
|
+
name: table,
|
|
117
|
+
columns: columns.map((col) => ({
|
|
118
|
+
name: col.name,
|
|
119
|
+
type: col.type,
|
|
120
|
+
nullable: col.notnull === 0,
|
|
121
|
+
defaultValue: col.dflt_value ?? void 0
|
|
122
|
+
}))
|
|
123
|
+
};
|
|
124
|
+
} catch {
|
|
125
|
+
try {
|
|
126
|
+
const columns = await adapter.all(`SELECT column_name, data_type, is_nullable, column_default
|
|
127
|
+
FROM information_schema.columns
|
|
128
|
+
WHERE table_schema = current_schema() AND table_name = $1
|
|
129
|
+
ORDER BY ordinal_position`, [table]);
|
|
130
|
+
return {
|
|
131
|
+
name: table,
|
|
132
|
+
columns: columns.map((col) => ({
|
|
133
|
+
name: col.column_name,
|
|
134
|
+
type: col.data_type,
|
|
135
|
+
nullable: col.is_nullable === "YES",
|
|
136
|
+
defaultValue: col.column_default ?? void 0
|
|
137
|
+
}))
|
|
138
|
+
};
|
|
139
|
+
} catch {
|
|
140
|
+
return {
|
|
141
|
+
name: table,
|
|
142
|
+
columns: []
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function generateCreateTableSQL(schema) {
|
|
148
|
+
if (schema.columns.length === 0) {
|
|
149
|
+
return `CREATE TABLE ${escapeIdentifier(schema.name)} ();`;
|
|
150
|
+
}
|
|
151
|
+
const columnDefs = schema.columns.map((col) => {
|
|
152
|
+
let def = ` ${escapeIdentifier(col.name)} ${col.type}`;
|
|
153
|
+
if (!col.nullable)
|
|
154
|
+
def += " NOT NULL";
|
|
155
|
+
if (col.defaultValue)
|
|
156
|
+
def += ` DEFAULT ${col.defaultValue}`;
|
|
157
|
+
return def;
|
|
158
|
+
});
|
|
159
|
+
return `CREATE TABLE ${escapeIdentifier(schema.name)} (
|
|
160
|
+
${columnDefs.join(",\n")}
|
|
161
|
+
);`;
|
|
162
|
+
}
|
|
163
|
+
function generateInsertSQL(table, row) {
|
|
164
|
+
const columns = Object.keys(row);
|
|
165
|
+
const values = columns.map((col) => escapeSQLValue(row[col]));
|
|
166
|
+
return `INSERT INTO ${escapeIdentifier(table)} (${columns.map(escapeIdentifier).join(", ")}) VALUES (${values.join(", ")});`;
|
|
167
|
+
}
|
|
168
|
+
function escapeIdentifier(identifier) {
|
|
169
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
170
|
+
}
|
|
171
|
+
function escapeSQLValue(value) {
|
|
172
|
+
if (value === null || value === void 0)
|
|
173
|
+
return "NULL";
|
|
174
|
+
if (typeof value === "number")
|
|
175
|
+
return String(value);
|
|
176
|
+
if (typeof value === "boolean")
|
|
177
|
+
return value ? "1" : "0";
|
|
178
|
+
if (value instanceof Date)
|
|
179
|
+
return `'${value.toISOString()}'`;
|
|
180
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
181
|
+
}
|
|
182
|
+
function escapeCSVValue(value) {
|
|
183
|
+
if (value.includes(",") || value.includes('"') || value.includes("\n")) {
|
|
184
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
185
|
+
}
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
189
|
+
0 && (module.exports = {
|
|
190
|
+
exportAsCSV,
|
|
191
|
+
exportAsJSON,
|
|
192
|
+
exportAsSQL,
|
|
193
|
+
exportData
|
|
194
|
+
});
|