@fileverse/api 0.0.2 → 0.0.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/dist/cli/index.js +184 -185
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/index.js +1133 -706
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +3001 -2434
- package/dist/index.js.map +1 -1
- package/dist/worker.js +2676 -2255
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/index.js
CHANGED
|
@@ -1,31 +1,58 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
2
11
|
|
|
3
|
-
//
|
|
4
|
-
import { Command as Command9 } from "commander";
|
|
5
|
-
|
|
6
|
-
// src/config/index.ts
|
|
7
|
-
import dotenv from "dotenv";
|
|
12
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
8
13
|
import path from "path";
|
|
9
|
-
import
|
|
10
|
-
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
|
+
var init_esm_shims = __esm({
|
|
16
|
+
"node_modules/tsup/assets/esm_shims.js"() {
|
|
17
|
+
"use strict";
|
|
18
|
+
}
|
|
19
|
+
});
|
|
11
20
|
|
|
12
21
|
// src/cli/constants.generated.ts
|
|
13
|
-
var STATIC_CONFIG
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
var STATIC_CONFIG;
|
|
23
|
+
var init_constants_generated = __esm({
|
|
24
|
+
"src/cli/constants.generated.ts"() {
|
|
25
|
+
"use strict";
|
|
26
|
+
init_esm_shims();
|
|
27
|
+
STATIC_CONFIG = {
|
|
28
|
+
API_URL: "https://prod-apps-storage-5cdacc06ff79.herokuapp.com/",
|
|
29
|
+
SERVER_DID: "did:key:z6Mkroj9bxTin6Z5S9qwx2G2b87NPrCX7S85FhCpmBGPcDCz",
|
|
30
|
+
PROXY_SERVER_DID: "did:key:z6MkrZSmq8D6vQG87YbjUQatXeptaCCXWdTx8fYaWxWbRUHB",
|
|
31
|
+
NETWORK_NAME: "gnosis",
|
|
32
|
+
DEFAULT_PORT: "8001",
|
|
33
|
+
DEFAULT_RPC_URL: "https://rpc.gnosischain.com",
|
|
34
|
+
PIMLICO_PROXY_URL: "https://pimlico-proxy-0a326da116f8.herokuapp.com/",
|
|
35
|
+
SERVICE_NAME: "fileverse-api",
|
|
36
|
+
LOG_LEVEL: "info",
|
|
37
|
+
FRONTEND_URL: "https://docs.fileverse.io"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// src/cli/constants.ts
|
|
43
|
+
var init_constants = __esm({
|
|
44
|
+
"src/cli/constants.ts"() {
|
|
45
|
+
"use strict";
|
|
46
|
+
init_esm_shims();
|
|
47
|
+
init_constants_generated();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
25
50
|
|
|
26
51
|
// src/config/index.ts
|
|
27
|
-
|
|
28
|
-
|
|
52
|
+
import dotenv from "dotenv";
|
|
53
|
+
import path2 from "path";
|
|
54
|
+
import fs from "fs";
|
|
55
|
+
import os from "os";
|
|
29
56
|
function getEnvPath() {
|
|
30
57
|
if (fs.existsSync(projectEnvPath)) {
|
|
31
58
|
return projectEnvPath;
|
|
@@ -36,7 +63,6 @@ function loadConfig(override = true) {
|
|
|
36
63
|
const envPath = getEnvPath();
|
|
37
64
|
dotenv.config({ path: envPath, override });
|
|
38
65
|
}
|
|
39
|
-
loadConfig(false);
|
|
40
66
|
function getRuntimeConfig() {
|
|
41
67
|
return {
|
|
42
68
|
get API_KEY() {
|
|
@@ -62,435 +88,538 @@ function getRuntimeConfig() {
|
|
|
62
88
|
}
|
|
63
89
|
};
|
|
64
90
|
}
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
var projectEnvPath, userEnvPath, config;
|
|
92
|
+
var init_config = __esm({
|
|
93
|
+
"src/config/index.ts"() {
|
|
94
|
+
"use strict";
|
|
95
|
+
init_esm_shims();
|
|
96
|
+
init_constants();
|
|
97
|
+
projectEnvPath = path2.join(process.cwd(), "config", ".env");
|
|
98
|
+
userEnvPath = path2.join(os.homedir(), ".fileverse", ".env");
|
|
99
|
+
loadConfig(false);
|
|
100
|
+
config = {
|
|
101
|
+
...STATIC_CONFIG,
|
|
102
|
+
get SERVICE_NAME() {
|
|
103
|
+
return STATIC_CONFIG.SERVICE_NAME;
|
|
104
|
+
},
|
|
105
|
+
get LOG_LEVEL() {
|
|
106
|
+
return STATIC_CONFIG.LOG_LEVEL;
|
|
107
|
+
},
|
|
108
|
+
get NETWORK_NAME() {
|
|
109
|
+
return STATIC_CONFIG.NETWORK_NAME;
|
|
110
|
+
},
|
|
111
|
+
get UPLOAD_SERVER_URL() {
|
|
112
|
+
return STATIC_CONFIG.API_URL;
|
|
113
|
+
},
|
|
114
|
+
get UPLOAD_SERVER_DID() {
|
|
115
|
+
return STATIC_CONFIG.SERVER_DID;
|
|
116
|
+
},
|
|
117
|
+
get API_KEY() {
|
|
118
|
+
return process.env.API_KEY;
|
|
119
|
+
},
|
|
120
|
+
get RPC_URL() {
|
|
121
|
+
return process.env.RPC_URL || STATIC_CONFIG.DEFAULT_RPC_URL;
|
|
122
|
+
},
|
|
123
|
+
get DB_PATH() {
|
|
124
|
+
return process.env.DB_PATH;
|
|
125
|
+
},
|
|
126
|
+
get DATABASE_URL() {
|
|
127
|
+
return process.env.DATABASE_URL;
|
|
128
|
+
},
|
|
129
|
+
get PORT() {
|
|
130
|
+
return process.env.PORT || STATIC_CONFIG.DEFAULT_PORT;
|
|
131
|
+
},
|
|
132
|
+
get NODE_ENV() {
|
|
133
|
+
return process.env.NODE_ENV || "production";
|
|
134
|
+
},
|
|
135
|
+
get IP() {
|
|
136
|
+
return process.env.IP || "0.0.0.0";
|
|
137
|
+
},
|
|
138
|
+
get FRONTEND_URL() {
|
|
139
|
+
return process.env.FRONTEND_URL || STATIC_CONFIG.FRONTEND_URL;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
105
142
|
}
|
|
106
|
-
};
|
|
143
|
+
});
|
|
107
144
|
|
|
108
145
|
// src/infra/logger.ts
|
|
109
146
|
import pino from "pino";
|
|
110
|
-
var isProduction
|
|
111
|
-
var
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
var isProduction, pinoInstance, createLogMethod, logger;
|
|
148
|
+
var init_logger = __esm({
|
|
149
|
+
"src/infra/logger.ts"() {
|
|
150
|
+
"use strict";
|
|
151
|
+
init_esm_shims();
|
|
152
|
+
init_constants();
|
|
153
|
+
init_config();
|
|
154
|
+
isProduction = config.NODE_ENV === "production";
|
|
155
|
+
pinoInstance = pino({
|
|
156
|
+
name: STATIC_CONFIG.SERVICE_NAME,
|
|
157
|
+
level: STATIC_CONFIG.LOG_LEVEL,
|
|
158
|
+
formatters: {
|
|
159
|
+
bindings: (bindings) => ({ name: bindings.name }),
|
|
160
|
+
level: (label) => ({ level: label })
|
|
161
|
+
},
|
|
162
|
+
serializers: {
|
|
163
|
+
err(err) {
|
|
164
|
+
if (!err) return err;
|
|
165
|
+
if (isProduction) {
|
|
166
|
+
return { type: err.name, message: err.message };
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
type: err.name,
|
|
170
|
+
message: err.message,
|
|
171
|
+
stack: err.stack
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
transport: config.NODE_ENV !== "production" ? {
|
|
176
|
+
target: "pino-pretty",
|
|
177
|
+
options: {
|
|
178
|
+
colorize: true,
|
|
179
|
+
translateTime: "SYS:standard",
|
|
180
|
+
ignore: "pid,hostname",
|
|
181
|
+
errorProps: "*",
|
|
182
|
+
errorLikeObjectKeys: ["err", "error"]
|
|
183
|
+
}
|
|
184
|
+
} : void 0
|
|
185
|
+
});
|
|
186
|
+
createLogMethod = (level) => {
|
|
187
|
+
return (...args) => {
|
|
188
|
+
const [first, ...rest] = args;
|
|
189
|
+
const log = pinoInstance[level].bind(pinoInstance);
|
|
190
|
+
if (typeof first === "object" && first !== null && !(first instanceof Error)) {
|
|
191
|
+
log(first, ...rest);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (rest.length > 0) {
|
|
195
|
+
const last = rest[rest.length - 1];
|
|
196
|
+
if (last instanceof Error) {
|
|
197
|
+
log({ err: last }, first, ...rest.slice(0, -1));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (first instanceof Error) {
|
|
202
|
+
log({ err: first }, first.message);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
log(first, ...rest);
|
|
128
206
|
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
207
|
+
};
|
|
208
|
+
logger = {
|
|
209
|
+
trace: createLogMethod("trace"),
|
|
210
|
+
debug: createLogMethod("debug"),
|
|
211
|
+
info: createLogMethod("info"),
|
|
212
|
+
warn: createLogMethod("warn"),
|
|
213
|
+
error: createLogMethod("error"),
|
|
214
|
+
fatal: createLogMethod("fatal"),
|
|
215
|
+
get level() {
|
|
216
|
+
return pinoInstance.level;
|
|
217
|
+
},
|
|
218
|
+
set level(lvl) {
|
|
219
|
+
pinoInstance.level = lvl;
|
|
220
|
+
},
|
|
221
|
+
child: pinoInstance.child.bind(pinoInstance)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
141
224
|
});
|
|
142
|
-
var createLogMethod = (level) => {
|
|
143
|
-
return (...args) => {
|
|
144
|
-
const [first, ...rest] = args;
|
|
145
|
-
const log = pinoInstance[level].bind(pinoInstance);
|
|
146
|
-
if (typeof first === "object" && first !== null && !(first instanceof Error)) {
|
|
147
|
-
log(first, ...rest);
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
if (rest.length > 0) {
|
|
151
|
-
const last = rest[rest.length - 1];
|
|
152
|
-
if (last instanceof Error) {
|
|
153
|
-
log({ err: last }, first, ...rest.slice(0, -1));
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (first instanceof Error) {
|
|
158
|
-
log({ err: first }, first.message);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
log(first, ...rest);
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
var logger = {
|
|
165
|
-
trace: createLogMethod("trace"),
|
|
166
|
-
debug: createLogMethod("debug"),
|
|
167
|
-
info: createLogMethod("info"),
|
|
168
|
-
warn: createLogMethod("warn"),
|
|
169
|
-
error: createLogMethod("error"),
|
|
170
|
-
fatal: createLogMethod("fatal"),
|
|
171
|
-
get level() {
|
|
172
|
-
return pinoInstance.level;
|
|
173
|
-
},
|
|
174
|
-
set level(lvl) {
|
|
175
|
-
pinoInstance.level = lvl;
|
|
176
|
-
},
|
|
177
|
-
child: pinoInstance.child.bind(pinoInstance)
|
|
178
|
-
};
|
|
179
225
|
|
|
180
|
-
// src/infra/
|
|
181
|
-
|
|
226
|
+
// src/infra/asyncHandler.ts
|
|
227
|
+
var init_asyncHandler = __esm({
|
|
228
|
+
"src/infra/asyncHandler.ts"() {
|
|
229
|
+
"use strict";
|
|
230
|
+
init_esm_shims();
|
|
231
|
+
}
|
|
232
|
+
});
|
|
182
233
|
|
|
183
234
|
// src/domain/file/constants.ts
|
|
184
|
-
var DEFAULT_LIST_LIMIT
|
|
235
|
+
var DEFAULT_LIST_LIMIT;
|
|
236
|
+
var init_constants2 = __esm({
|
|
237
|
+
"src/domain/file/constants.ts"() {
|
|
238
|
+
"use strict";
|
|
239
|
+
init_esm_shims();
|
|
240
|
+
DEFAULT_LIST_LIMIT = 10;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
185
243
|
|
|
186
244
|
// src/infra/database/query-builder.ts
|
|
187
|
-
var QueryBuilder
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
245
|
+
var QueryBuilder;
|
|
246
|
+
var init_query_builder = __esm({
|
|
247
|
+
"src/infra/database/query-builder.ts"() {
|
|
248
|
+
"use strict";
|
|
249
|
+
init_esm_shims();
|
|
250
|
+
init_connection();
|
|
251
|
+
init_constants2();
|
|
252
|
+
QueryBuilder = class {
|
|
253
|
+
static async select(sql, params = []) {
|
|
254
|
+
const adapter2 = await getAdapter();
|
|
255
|
+
return adapter2.select(sql, params);
|
|
256
|
+
}
|
|
257
|
+
static async selectOne(sql, params = []) {
|
|
258
|
+
const adapter2 = await getAdapter();
|
|
259
|
+
return adapter2.selectOne(sql, params);
|
|
260
|
+
}
|
|
261
|
+
static async execute(sql, params = []) {
|
|
262
|
+
const adapter2 = await getAdapter();
|
|
263
|
+
return adapter2.execute(sql, params);
|
|
264
|
+
}
|
|
265
|
+
static async transaction(callback) {
|
|
266
|
+
const adapter2 = await getAdapter();
|
|
267
|
+
return adapter2.transaction(callback);
|
|
268
|
+
}
|
|
269
|
+
static paginate(sql, options = {}) {
|
|
270
|
+
let query = sql;
|
|
271
|
+
if (options.orderBy) {
|
|
272
|
+
query += ` ORDER BY ${options.orderBy} ${options.orderDirection || "ASC"}`;
|
|
273
|
+
}
|
|
274
|
+
const hasOffset = (options.offset ?? 0) > 0;
|
|
275
|
+
const limit = options.limit ?? (hasOffset ? DEFAULT_LIST_LIMIT : void 0);
|
|
276
|
+
if (limit) {
|
|
277
|
+
query += ` LIMIT ${limit}`;
|
|
278
|
+
}
|
|
279
|
+
if (hasOffset) {
|
|
280
|
+
query += ` OFFSET ${options.offset}`;
|
|
281
|
+
}
|
|
282
|
+
return query;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
199
285
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
return query;
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// src/infra/database/index.ts
|
|
289
|
+
var closeDatabase;
|
|
290
|
+
var init_database = __esm({
|
|
291
|
+
"src/infra/database/index.ts"() {
|
|
292
|
+
"use strict";
|
|
293
|
+
init_esm_shims();
|
|
294
|
+
init_connection();
|
|
295
|
+
init_query_builder();
|
|
296
|
+
closeDatabase = async () => {
|
|
297
|
+
await closeAdapter();
|
|
298
|
+
};
|
|
214
299
|
}
|
|
215
|
-
};
|
|
300
|
+
});
|
|
216
301
|
|
|
217
302
|
// src/infra/database/models/files.model.ts
|
|
218
303
|
import { uuidv7 } from "uuidv7";
|
|
219
|
-
var FilesModel
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
304
|
+
var FilesModel;
|
|
305
|
+
var init_files_model = __esm({
|
|
306
|
+
"src/infra/database/models/files.model.ts"() {
|
|
307
|
+
"use strict";
|
|
308
|
+
init_esm_shims();
|
|
309
|
+
init_database();
|
|
310
|
+
FilesModel = class {
|
|
311
|
+
static TABLE = "files";
|
|
312
|
+
static parseFile(fileRaw) {
|
|
313
|
+
let metadata = {};
|
|
314
|
+
try {
|
|
315
|
+
if (fileRaw.metadata) {
|
|
316
|
+
metadata = typeof fileRaw.metadata === "string" ? JSON.parse(fileRaw.metadata) : fileRaw.metadata;
|
|
317
|
+
}
|
|
318
|
+
} catch (e) {
|
|
319
|
+
metadata = {};
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
_id: fileRaw._id,
|
|
323
|
+
ddocId: fileRaw.ddocId,
|
|
324
|
+
title: fileRaw.title,
|
|
325
|
+
content: fileRaw.content,
|
|
326
|
+
localVersion: fileRaw.localVersion,
|
|
327
|
+
onchainVersion: fileRaw.onchainVersion,
|
|
328
|
+
syncStatus: fileRaw.syncStatus,
|
|
329
|
+
isDeleted: fileRaw.isDeleted,
|
|
330
|
+
onChainFileId: fileRaw.onChainFileId ?? null,
|
|
331
|
+
portalAddress: fileRaw.portalAddress,
|
|
332
|
+
metadata: metadata || {},
|
|
333
|
+
createdAt: fileRaw.createdAt,
|
|
334
|
+
updatedAt: fileRaw.updatedAt,
|
|
335
|
+
linkKey: fileRaw.linkKey,
|
|
336
|
+
linkKeyNonce: fileRaw.linkKeyNonce,
|
|
337
|
+
commentKey: fileRaw.commentKey,
|
|
338
|
+
link: fileRaw.link
|
|
339
|
+
};
|
|
226
340
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
_id: fileRaw._id,
|
|
232
|
-
ddocId: fileRaw.ddocId,
|
|
233
|
-
title: fileRaw.title,
|
|
234
|
-
content: fileRaw.content,
|
|
235
|
-
localVersion: fileRaw.localVersion,
|
|
236
|
-
onchainVersion: fileRaw.onchainVersion,
|
|
237
|
-
syncStatus: fileRaw.syncStatus,
|
|
238
|
-
isDeleted: fileRaw.isDeleted,
|
|
239
|
-
onChainFileId: fileRaw.onChainFileId ?? null,
|
|
240
|
-
portalAddress: fileRaw.portalAddress,
|
|
241
|
-
metadata: metadata || {},
|
|
242
|
-
createdAt: fileRaw.createdAt,
|
|
243
|
-
updatedAt: fileRaw.updatedAt,
|
|
244
|
-
linkKey: fileRaw.linkKey,
|
|
245
|
-
linkKeyNonce: fileRaw.linkKeyNonce,
|
|
246
|
-
commentKey: fileRaw.commentKey,
|
|
247
|
-
link: fileRaw.link
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
static async findAll(portalAddress, limit, skip) {
|
|
251
|
-
const whereClause = "isDeleted = 0 AND portalAddress = ?";
|
|
252
|
-
const params = [portalAddress];
|
|
253
|
-
const countSql = `
|
|
341
|
+
static async findAll(portalAddress, limit, skip) {
|
|
342
|
+
const whereClause = "isDeleted = 0 AND portalAddress = ?";
|
|
343
|
+
const params = [portalAddress];
|
|
344
|
+
const countSql = `
|
|
254
345
|
SELECT COUNT(*) as count
|
|
255
346
|
FROM ${this.TABLE}
|
|
256
347
|
WHERE ${whereClause}
|
|
257
348
|
`;
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
349
|
+
const totalResult = await QueryBuilder.selectOne(countSql, params);
|
|
350
|
+
const total = totalResult?.count || 0;
|
|
351
|
+
const sql = `
|
|
261
352
|
SELECT *
|
|
262
353
|
FROM ${this.TABLE}
|
|
263
354
|
WHERE ${whereClause}
|
|
264
355
|
`;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
356
|
+
const completeSql = QueryBuilder.paginate(sql, {
|
|
357
|
+
limit,
|
|
358
|
+
offset: skip,
|
|
359
|
+
orderBy: "createdAt",
|
|
360
|
+
orderDirection: "DESC"
|
|
361
|
+
});
|
|
362
|
+
const filesRaw = await QueryBuilder.select(completeSql, params);
|
|
363
|
+
const files = filesRaw.map(this.parseFile);
|
|
364
|
+
const hasNext = skip !== void 0 && limit !== void 0 ? skip + limit < total : false;
|
|
365
|
+
return { files, total, hasNext };
|
|
366
|
+
}
|
|
367
|
+
static async findById(_id, portalAddress) {
|
|
368
|
+
const sql = `
|
|
278
369
|
SELECT *
|
|
279
370
|
FROM ${this.TABLE}
|
|
280
371
|
WHERE _id = ? AND isDeleted = 0 AND portalAddress = ?
|
|
281
372
|
`;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
373
|
+
const result = await QueryBuilder.selectOne(sql, [_id, portalAddress]);
|
|
374
|
+
return result ? this.parseFile(result) : void 0;
|
|
375
|
+
}
|
|
376
|
+
static async findByIdIncludingDeleted(_id) {
|
|
377
|
+
const sql = `
|
|
287
378
|
SELECT *
|
|
288
379
|
FROM ${this.TABLE}
|
|
289
380
|
WHERE _id = ?
|
|
290
381
|
`;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
382
|
+
const result = await QueryBuilder.selectOne(sql, [_id]);
|
|
383
|
+
return result ? this.parseFile(result) : void 0;
|
|
384
|
+
}
|
|
385
|
+
static async findByIdExcludingDeleted(_id) {
|
|
386
|
+
const sql = `
|
|
296
387
|
SELECT *
|
|
297
388
|
FROM ${this.TABLE}
|
|
298
389
|
WHERE _id = ? AND isDeleted = 0
|
|
299
390
|
`;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
391
|
+
const result = await QueryBuilder.selectOne(sql, [_id]);
|
|
392
|
+
return result ? this.parseFile(result) : void 0;
|
|
393
|
+
}
|
|
394
|
+
static async findByDDocId(ddocId, portalAddress) {
|
|
395
|
+
const sql = `
|
|
305
396
|
SELECT *
|
|
306
397
|
FROM ${this.TABLE}
|
|
307
398
|
WHERE ddocId = ? AND isDeleted = 0 AND portalAddress = ?
|
|
308
399
|
`;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
400
|
+
const result = await QueryBuilder.selectOne(sql, [ddocId, portalAddress]);
|
|
401
|
+
return result ? this.parseFile(result) : void 0;
|
|
402
|
+
}
|
|
403
|
+
static async searchByTitle(searchTerm, portalAddress, limit, skip) {
|
|
404
|
+
const sql = `
|
|
314
405
|
SELECT *
|
|
315
406
|
FROM ${this.TABLE}
|
|
316
407
|
WHERE LOWER(title) LIKE LOWER(?) AND isDeleted = 0 AND portalAddress = ?
|
|
317
408
|
`;
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
409
|
+
const completeSql = QueryBuilder.paginate(sql, {
|
|
410
|
+
limit,
|
|
411
|
+
offset: skip,
|
|
412
|
+
orderBy: "createdAt",
|
|
413
|
+
orderDirection: "DESC"
|
|
414
|
+
});
|
|
415
|
+
const filesRaw = await QueryBuilder.select(completeSql, [`%${searchTerm}%`, portalAddress]);
|
|
416
|
+
return filesRaw.map(this.parseFile);
|
|
417
|
+
}
|
|
418
|
+
static async create(input) {
|
|
419
|
+
const _id = uuidv7();
|
|
420
|
+
const sql = `
|
|
330
421
|
INSERT INTO ${this.TABLE}
|
|
331
422
|
(_id, title, content, ddocId, portalAddress)
|
|
332
423
|
VALUES (?, ?, ?, ?, ?)
|
|
333
424
|
`;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
return created;
|
|
340
|
-
}
|
|
341
|
-
static async update(_id, payload, portalAddress) {
|
|
342
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
343
|
-
const keys = [];
|
|
344
|
-
const values = [];
|
|
345
|
-
for (const [k, v] of Object.entries(payload)) {
|
|
346
|
-
if (v !== void 0) {
|
|
347
|
-
if (k === "metadata" && typeof v === "object") {
|
|
348
|
-
keys.push(`${k} = ?`);
|
|
349
|
-
values.push(JSON.stringify(v));
|
|
350
|
-
} else {
|
|
351
|
-
keys.push(`${k} = ?`);
|
|
352
|
-
values.push(v);
|
|
425
|
+
await QueryBuilder.execute(sql, [_id, input.title, input.content, input.ddocId, input.portalAddress]);
|
|
426
|
+
const created = await this.findById(_id, input.portalAddress);
|
|
427
|
+
if (!created) {
|
|
428
|
+
throw new Error("Failed to create file");
|
|
353
429
|
}
|
|
430
|
+
return created;
|
|
354
431
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
432
|
+
static async update(_id, payload, portalAddress) {
|
|
433
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
434
|
+
const keys = [];
|
|
435
|
+
const values = [];
|
|
436
|
+
for (const [k, v] of Object.entries(payload)) {
|
|
437
|
+
if (v !== void 0) {
|
|
438
|
+
if (k === "metadata" && typeof v === "object") {
|
|
439
|
+
keys.push(`${k} = ?`);
|
|
440
|
+
values.push(JSON.stringify(v));
|
|
441
|
+
} else {
|
|
442
|
+
keys.push(`${k} = ?`);
|
|
443
|
+
values.push(v);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
keys.push("updatedAt = ?");
|
|
448
|
+
values.push(now, _id, portalAddress);
|
|
449
|
+
const updateChain = keys.join(", ");
|
|
450
|
+
const sql = `UPDATE ${this.TABLE} SET ${updateChain} WHERE _id = ? AND portalAddress = ?`;
|
|
451
|
+
await QueryBuilder.execute(sql, values);
|
|
452
|
+
const updated = await this.findById(_id, portalAddress);
|
|
453
|
+
if (!updated) {
|
|
454
|
+
throw new Error("Failed to update file");
|
|
455
|
+
}
|
|
456
|
+
return updated;
|
|
457
|
+
}
|
|
458
|
+
static async softDelete(_id) {
|
|
459
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
460
|
+
const sql = `
|
|
370
461
|
UPDATE ${this.TABLE}
|
|
371
462
|
SET isDeleted = 1, syncStatus = 'pending', updatedAt = ?
|
|
372
463
|
WHERE _id = ?
|
|
373
464
|
`;
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
465
|
+
await QueryBuilder.execute(sql, [now, _id]);
|
|
466
|
+
const deleted = await this.findByIdIncludingDeleted(_id);
|
|
467
|
+
if (!deleted) {
|
|
468
|
+
throw new Error("Failed to delete file");
|
|
469
|
+
}
|
|
470
|
+
return deleted;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
380
473
|
}
|
|
381
|
-
};
|
|
474
|
+
});
|
|
382
475
|
|
|
383
476
|
// src/infra/database/models/portals.model.ts
|
|
384
477
|
import { uuidv7 as uuidv72 } from "uuidv7";
|
|
478
|
+
var init_portals_model = __esm({
|
|
479
|
+
"src/infra/database/models/portals.model.ts"() {
|
|
480
|
+
"use strict";
|
|
481
|
+
init_esm_shims();
|
|
482
|
+
init_database();
|
|
483
|
+
}
|
|
484
|
+
});
|
|
385
485
|
|
|
386
486
|
// src/infra/database/models/apikeys.model.ts
|
|
387
487
|
import { uuidv7 as uuidv73 } from "uuidv7";
|
|
388
|
-
var ApiKeysModel
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
488
|
+
var ApiKeysModel;
|
|
489
|
+
var init_apikeys_model = __esm({
|
|
490
|
+
"src/infra/database/models/apikeys.model.ts"() {
|
|
491
|
+
"use strict";
|
|
492
|
+
init_esm_shims();
|
|
493
|
+
init_database();
|
|
494
|
+
ApiKeysModel = class {
|
|
495
|
+
static TABLE = "api_keys";
|
|
496
|
+
static async create(input) {
|
|
497
|
+
const _id = uuidv73();
|
|
498
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
499
|
+
const sql = `INSERT INTO ${this.TABLE} (_id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt)
|
|
394
500
|
VALUES (?, ?, ?, ?, ?, ?)`;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
501
|
+
const result = await QueryBuilder.execute(sql, [
|
|
502
|
+
_id,
|
|
503
|
+
input.apiKeySeed,
|
|
504
|
+
input.name,
|
|
505
|
+
input.collaboratorAddress,
|
|
506
|
+
input.portalAddress,
|
|
507
|
+
now
|
|
508
|
+
]);
|
|
509
|
+
if (result.changes === 0) {
|
|
510
|
+
throw new Error("Failed to create API key");
|
|
511
|
+
}
|
|
512
|
+
const created = await this.findById(_id);
|
|
513
|
+
if (!created) {
|
|
514
|
+
throw new Error("Failed to create API key");
|
|
515
|
+
}
|
|
516
|
+
return created;
|
|
517
|
+
}
|
|
518
|
+
static async findById(_id) {
|
|
519
|
+
const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE _id = ? AND isDeleted = 0`;
|
|
520
|
+
return QueryBuilder.selectOne(sql, [_id]);
|
|
521
|
+
}
|
|
522
|
+
static async findByCollaboratorAddress(collaboratorAddress) {
|
|
523
|
+
const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE collaboratorAddress = ? AND isDeleted = 0 LIMIT 1`;
|
|
524
|
+
return QueryBuilder.selectOne(sql, [collaboratorAddress]);
|
|
525
|
+
}
|
|
526
|
+
static async delete(_id) {
|
|
527
|
+
const sql = `UPDATE ${this.TABLE} SET isDeleted = 1 WHERE _id = ?`;
|
|
528
|
+
await QueryBuilder.execute(sql, [_id]);
|
|
529
|
+
}
|
|
530
|
+
static async findByPortalAddress(portalAddress) {
|
|
531
|
+
const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE portalAddress = ? AND isDeleted = 0`;
|
|
532
|
+
return QueryBuilder.selectOne(sql, [portalAddress]);
|
|
533
|
+
}
|
|
534
|
+
static async findByApiKey(apiKey) {
|
|
535
|
+
const sql = `SELECT _id, apiKeySeed, name, collaboratorAddress, portalAddress, createdAt, isDeleted FROM ${this.TABLE} WHERE apiKeySeed = ? AND isDeleted = 0`;
|
|
536
|
+
return QueryBuilder.selectOne(sql, [apiKey]);
|
|
537
|
+
}
|
|
538
|
+
};
|
|
431
539
|
}
|
|
432
|
-
};
|
|
540
|
+
});
|
|
433
541
|
|
|
434
|
-
// src/infra/database/models/
|
|
435
|
-
|
|
542
|
+
// src/infra/database/models/folders.model.ts
|
|
543
|
+
var init_folders_model = __esm({
|
|
544
|
+
"src/infra/database/models/folders.model.ts"() {
|
|
545
|
+
"use strict";
|
|
546
|
+
init_esm_shims();
|
|
547
|
+
init_database();
|
|
548
|
+
}
|
|
549
|
+
});
|
|
436
550
|
|
|
437
551
|
// src/infra/worker/workerSignal.ts
|
|
438
552
|
import { EventEmitter } from "events";
|
|
439
|
-
var WorkerSignal = class extends EventEmitter {
|
|
440
|
-
};
|
|
441
|
-
var workerSignal = new WorkerSignal();
|
|
442
|
-
workerSignal.setMaxListeners(20);
|
|
443
553
|
function notifyNewEvent() {
|
|
444
554
|
workerSignal.emit("newEvent");
|
|
445
555
|
}
|
|
556
|
+
var WorkerSignal, workerSignal;
|
|
557
|
+
var init_workerSignal = __esm({
|
|
558
|
+
"src/infra/worker/workerSignal.ts"() {
|
|
559
|
+
"use strict";
|
|
560
|
+
init_esm_shims();
|
|
561
|
+
WorkerSignal = class extends EventEmitter {
|
|
562
|
+
};
|
|
563
|
+
workerSignal = new WorkerSignal();
|
|
564
|
+
workerSignal.setMaxListeners(20);
|
|
565
|
+
}
|
|
566
|
+
});
|
|
446
567
|
|
|
447
568
|
// src/infra/database/models/events.model.ts
|
|
448
|
-
|
|
449
|
-
var EventsModel
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
569
|
+
import { uuidv7 as uuidv74 } from "uuidv7";
|
|
570
|
+
var RETRY_DELAYS_MS, EventsModel;
|
|
571
|
+
var init_events_model = __esm({
|
|
572
|
+
"src/infra/database/models/events.model.ts"() {
|
|
573
|
+
"use strict";
|
|
574
|
+
init_esm_shims();
|
|
575
|
+
init_database();
|
|
576
|
+
init_workerSignal();
|
|
577
|
+
RETRY_DELAYS_MS = [5e3, 3e4, 12e4];
|
|
578
|
+
EventsModel = class {
|
|
579
|
+
static TABLE = "events";
|
|
580
|
+
static async create(input) {
|
|
581
|
+
const _id = uuidv74();
|
|
582
|
+
const timestamp = Date.now();
|
|
583
|
+
const status = "pending";
|
|
584
|
+
const sql = `
|
|
456
585
|
INSERT INTO ${this.TABLE}
|
|
457
586
|
(_id, type, timestamp, fileId, portalAddress, status, retryCount, lastError, lockedAt, nextRetryAt)
|
|
458
587
|
VALUES (?, ?, ?, ?, ?, ?, 0, NULL, NULL, NULL)
|
|
459
588
|
`;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
589
|
+
await QueryBuilder.execute(sql, [_id, input.type, timestamp, input.fileId, input.portalAddress, status]);
|
|
590
|
+
notifyNewEvent();
|
|
591
|
+
return {
|
|
592
|
+
_id,
|
|
593
|
+
type: input.type,
|
|
594
|
+
timestamp,
|
|
595
|
+
fileId: input.fileId,
|
|
596
|
+
portalAddress: input.portalAddress,
|
|
597
|
+
status,
|
|
598
|
+
retryCount: 0,
|
|
599
|
+
lastError: null,
|
|
600
|
+
lockedAt: null,
|
|
601
|
+
nextRetryAt: null
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
static async findById(_id) {
|
|
605
|
+
const sql = `SELECT * FROM ${this.TABLE} WHERE _id = ?`;
|
|
606
|
+
const row = await QueryBuilder.selectOne(sql, [_id]);
|
|
607
|
+
return row ? this.parseEvent(row) : void 0;
|
|
608
|
+
}
|
|
609
|
+
static async findNextPending() {
|
|
610
|
+
const sql = `
|
|
482
611
|
SELECT * FROM ${this.TABLE}
|
|
483
612
|
WHERE status = 'pending'
|
|
484
613
|
ORDER BY timestamp ASC
|
|
485
614
|
LIMIT 1
|
|
486
615
|
`;
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
616
|
+
const row = await QueryBuilder.selectOne(sql, []);
|
|
617
|
+
return row ? this.parseEvent(row) : void 0;
|
|
618
|
+
}
|
|
619
|
+
static async findNextEligible(lockedFileIds) {
|
|
620
|
+
const now = Date.now();
|
|
621
|
+
const exclusionClause = lockedFileIds.length > 0 ? `AND e1.fileId NOT IN (${lockedFileIds.map(() => "?").join(", ")})` : "";
|
|
622
|
+
const sql = `
|
|
494
623
|
SELECT e1.* FROM ${this.TABLE} e1
|
|
495
624
|
WHERE e1.status = 'pending'
|
|
496
625
|
AND (e1.nextRetryAt IS NULL OR e1.nextRetryAt <= ?)
|
|
@@ -504,34 +633,34 @@ var EventsModel = class {
|
|
|
504
633
|
ORDER BY e1.timestamp ASC
|
|
505
634
|
LIMIT 1
|
|
506
635
|
`;
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
636
|
+
const params = [now, ...lockedFileIds];
|
|
637
|
+
const row = await QueryBuilder.selectOne(sql, params);
|
|
638
|
+
return row ? this.parseEvent(row) : void 0;
|
|
639
|
+
}
|
|
640
|
+
static async markProcessing(_id) {
|
|
641
|
+
const sql = `
|
|
513
642
|
UPDATE ${this.TABLE}
|
|
514
643
|
SET status = 'processing',
|
|
515
644
|
lockedAt = ?
|
|
516
645
|
WHERE _id = ?
|
|
517
646
|
`;
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
647
|
+
await QueryBuilder.execute(sql, [Date.now(), _id]);
|
|
648
|
+
}
|
|
649
|
+
static async markProcessed(_id) {
|
|
650
|
+
const sql = `
|
|
522
651
|
UPDATE ${this.TABLE}
|
|
523
652
|
SET status = 'processed',
|
|
524
653
|
lockedAt = NULL
|
|
525
654
|
WHERE _id = ?
|
|
526
655
|
`;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
656
|
+
await QueryBuilder.execute(sql, [_id]);
|
|
657
|
+
}
|
|
658
|
+
static async scheduleRetry(_id, errorMsg) {
|
|
659
|
+
const event = await this.findById(_id);
|
|
660
|
+
if (!event) return;
|
|
661
|
+
const delay = RETRY_DELAYS_MS[Math.min(event.retryCount, RETRY_DELAYS_MS.length - 1)];
|
|
662
|
+
const nextRetryAt = Date.now() + delay;
|
|
663
|
+
const sql = `
|
|
535
664
|
UPDATE ${this.TABLE}
|
|
536
665
|
SET status = 'pending',
|
|
537
666
|
retryCount = retryCount + 1,
|
|
@@ -540,11 +669,11 @@ var EventsModel = class {
|
|
|
540
669
|
lockedAt = NULL
|
|
541
670
|
WHERE _id = ?
|
|
542
671
|
`;
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
672
|
+
await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);
|
|
673
|
+
}
|
|
674
|
+
static async scheduleRetryAfter(_id, errorMsg, retryAfterMs) {
|
|
675
|
+
const nextRetryAt = Date.now() + retryAfterMs;
|
|
676
|
+
const sql = `
|
|
548
677
|
UPDATE ${this.TABLE}
|
|
549
678
|
SET status = 'pending',
|
|
550
679
|
lastError = ?,
|
|
@@ -552,33 +681,33 @@ var EventsModel = class {
|
|
|
552
681
|
lockedAt = NULL
|
|
553
682
|
WHERE _id = ?
|
|
554
683
|
`;
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
684
|
+
await QueryBuilder.execute(sql, [errorMsg, nextRetryAt, _id]);
|
|
685
|
+
}
|
|
686
|
+
static async markFailed(_id, errorMsg) {
|
|
687
|
+
const sql = `
|
|
559
688
|
UPDATE ${this.TABLE}
|
|
560
689
|
SET status = 'failed',
|
|
561
690
|
lastError = ?,
|
|
562
691
|
lockedAt = NULL
|
|
563
692
|
WHERE _id = ?
|
|
564
693
|
`;
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
694
|
+
await QueryBuilder.execute(sql, [errorMsg, _id]);
|
|
695
|
+
}
|
|
696
|
+
static async listFailed(portalAddress) {
|
|
697
|
+
const portalClause = portalAddress != null ? "AND portalAddress = ?" : "";
|
|
698
|
+
const sql = `
|
|
570
699
|
SELECT * FROM ${this.TABLE}
|
|
571
700
|
WHERE status = 'failed'
|
|
572
701
|
${portalClause}
|
|
573
702
|
ORDER BY timestamp ASC
|
|
574
703
|
`;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
704
|
+
const params = portalAddress != null ? [portalAddress] : [];
|
|
705
|
+
const rows = await QueryBuilder.select(sql, params);
|
|
706
|
+
return rows.map((row) => this.parseEvent(row));
|
|
707
|
+
}
|
|
708
|
+
static async resetFailedToPending(_id, portalAddress) {
|
|
709
|
+
const portalClause = portalAddress != null ? "AND portalAddress = ?" : "";
|
|
710
|
+
const sql = `
|
|
582
711
|
UPDATE ${this.TABLE}
|
|
583
712
|
SET status = 'pending',
|
|
584
713
|
retryCount = 0,
|
|
@@ -589,16 +718,16 @@ var EventsModel = class {
|
|
|
589
718
|
AND status = 'failed'
|
|
590
719
|
${portalClause}
|
|
591
720
|
`;
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
721
|
+
const params = portalAddress != null ? [_id, portalAddress] : [_id];
|
|
722
|
+
const result = await QueryBuilder.execute(sql, params);
|
|
723
|
+
if (result.changes > 0) {
|
|
724
|
+
notifyNewEvent();
|
|
725
|
+
}
|
|
726
|
+
return result.changes > 0;
|
|
727
|
+
}
|
|
728
|
+
static async resetAllFailedToPending(portalAddress) {
|
|
729
|
+
const portalClause = portalAddress != null ? "AND portalAddress = ?" : "";
|
|
730
|
+
const sql = `
|
|
602
731
|
UPDATE ${this.TABLE}
|
|
603
732
|
SET status = 'pending',
|
|
604
733
|
retryCount = 0,
|
|
@@ -608,15 +737,15 @@ var EventsModel = class {
|
|
|
608
737
|
WHERE status = 'failed'
|
|
609
738
|
${portalClause}
|
|
610
739
|
`;
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
740
|
+
const params = portalAddress != null ? [portalAddress] : [];
|
|
741
|
+
const result = await QueryBuilder.execute(sql, params);
|
|
742
|
+
if (result.changes > 0) {
|
|
743
|
+
notifyNewEvent();
|
|
744
|
+
}
|
|
745
|
+
return result.changes;
|
|
746
|
+
}
|
|
747
|
+
static async resetStaleEvents(staleThreshold) {
|
|
748
|
+
const sql = `
|
|
620
749
|
UPDATE ${this.TABLE}
|
|
621
750
|
SET status = 'pending',
|
|
622
751
|
lockedAt = NULL,
|
|
@@ -626,51 +755,113 @@ var EventsModel = class {
|
|
|
626
755
|
AND lockedAt IS NOT NULL
|
|
627
756
|
AND lockedAt < ?
|
|
628
757
|
`;
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
758
|
+
const result = await QueryBuilder.execute(sql, [staleThreshold]);
|
|
759
|
+
return result.changes;
|
|
760
|
+
}
|
|
761
|
+
static async setEventPendingOp(_id, userOpHash, payload) {
|
|
762
|
+
const sql = `UPDATE ${this.TABLE} SET userOpHash = ?, pendingPayload = ? WHERE _id = ?`;
|
|
763
|
+
await QueryBuilder.execute(sql, [userOpHash, JSON.stringify(payload), _id]);
|
|
764
|
+
}
|
|
765
|
+
static async clearEventPendingOp(_id) {
|
|
766
|
+
const sql = `UPDATE ${this.TABLE} SET userOpHash = NULL, pendingPayload = NULL WHERE _id = ?`;
|
|
767
|
+
await QueryBuilder.execute(sql, [_id]);
|
|
768
|
+
}
|
|
769
|
+
static parseEvent(row) {
|
|
770
|
+
return {
|
|
771
|
+
_id: row._id,
|
|
772
|
+
type: row.type,
|
|
773
|
+
timestamp: row.timestamp,
|
|
774
|
+
fileId: row.fileId,
|
|
775
|
+
portalAddress: row.portalAddress ?? "",
|
|
776
|
+
status: row.status,
|
|
777
|
+
retryCount: row.retryCount,
|
|
778
|
+
lastError: row.lastError,
|
|
779
|
+
lockedAt: row.lockedAt,
|
|
780
|
+
nextRetryAt: row.nextRetryAt,
|
|
781
|
+
userOpHash: row.userOpHash ?? null,
|
|
782
|
+
pendingPayload: row.pendingPayload ?? null
|
|
783
|
+
};
|
|
784
|
+
}
|
|
654
785
|
};
|
|
655
786
|
}
|
|
656
|
-
};
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
// src/infra/database/models/index.ts
|
|
790
|
+
var init_models = __esm({
|
|
791
|
+
"src/infra/database/models/index.ts"() {
|
|
792
|
+
"use strict";
|
|
793
|
+
init_esm_shims();
|
|
794
|
+
init_files_model();
|
|
795
|
+
init_portals_model();
|
|
796
|
+
init_apikeys_model();
|
|
797
|
+
init_folders_model();
|
|
798
|
+
init_events_model();
|
|
799
|
+
}
|
|
800
|
+
});
|
|
657
801
|
|
|
658
802
|
// src/sdk/key-store.ts
|
|
659
803
|
import { eciesDecrypt, eciesEncrypt, generateECKeyPair } from "@fileverse/crypto/ecies";
|
|
804
|
+
var init_key_store = __esm({
|
|
805
|
+
"src/sdk/key-store.ts"() {
|
|
806
|
+
"use strict";
|
|
807
|
+
init_esm_shims();
|
|
808
|
+
}
|
|
809
|
+
});
|
|
660
810
|
|
|
661
811
|
// src/sdk/auth-token-provider.ts
|
|
662
812
|
import * as ucans from "@ucans/ucans";
|
|
813
|
+
var init_auth_token_provider = __esm({
|
|
814
|
+
"src/sdk/auth-token-provider.ts"() {
|
|
815
|
+
"use strict";
|
|
816
|
+
init_esm_shims();
|
|
817
|
+
}
|
|
818
|
+
});
|
|
663
819
|
|
|
664
|
-
// src/
|
|
665
|
-
import {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
820
|
+
// src/constants/chains.ts
|
|
821
|
+
import { sepolia, gnosis } from "viem/chains";
|
|
822
|
+
var init_chains = __esm({
|
|
823
|
+
"src/constants/chains.ts"() {
|
|
824
|
+
"use strict";
|
|
825
|
+
init_esm_shims();
|
|
826
|
+
}
|
|
827
|
+
});
|
|
670
828
|
|
|
671
|
-
// src/
|
|
672
|
-
|
|
673
|
-
|
|
829
|
+
// src/constants/events.ts
|
|
830
|
+
var init_events = __esm({
|
|
831
|
+
"src/constants/events.ts"() {
|
|
832
|
+
"use strict";
|
|
833
|
+
init_esm_shims();
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
// src/constants/methods.ts
|
|
838
|
+
var init_methods = __esm({
|
|
839
|
+
"src/constants/methods.ts"() {
|
|
840
|
+
"use strict";
|
|
841
|
+
init_esm_shims();
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
// src/constants/index.ts
|
|
846
|
+
var NETWORK_NAME, UPLOAD_SERVER_URL, CHAIN_MAP, CHAIN;
|
|
847
|
+
var init_constants3 = __esm({
|
|
848
|
+
"src/constants/index.ts"() {
|
|
849
|
+
"use strict";
|
|
850
|
+
init_esm_shims();
|
|
851
|
+
init_constants();
|
|
852
|
+
init_config();
|
|
853
|
+
init_chains();
|
|
854
|
+
init_events();
|
|
855
|
+
init_methods();
|
|
856
|
+
NETWORK_NAME = STATIC_CONFIG.NETWORK_NAME;
|
|
857
|
+
UPLOAD_SERVER_URL = STATIC_CONFIG.API_URL;
|
|
858
|
+
CHAIN_MAP = {
|
|
859
|
+
gnosis,
|
|
860
|
+
sepolia
|
|
861
|
+
};
|
|
862
|
+
CHAIN = CHAIN_MAP[NETWORK_NAME];
|
|
863
|
+
}
|
|
864
|
+
});
|
|
674
865
|
|
|
675
866
|
// src/sdk/pimlico-utils.ts
|
|
676
867
|
import { createPublicClient, http, hexToBigInt, toHex, toBytes } from "viem";
|
|
@@ -678,24 +869,35 @@ import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
|
678
869
|
import { createSmartAccountClient } from "permissionless";
|
|
679
870
|
import { toSafeSmartAccount } from "permissionless/accounts";
|
|
680
871
|
import { entryPoint07Address } from "viem/account-abstraction";
|
|
681
|
-
|
|
682
|
-
// src/constants/chains.ts
|
|
683
|
-
import { sepolia, gnosis } from "viem/chains";
|
|
684
|
-
|
|
685
|
-
// src/constants/index.ts
|
|
686
|
-
var NETWORK_NAME = STATIC_CONFIG.NETWORK_NAME;
|
|
687
|
-
var UPLOAD_SERVER_URL = STATIC_CONFIG.API_URL;
|
|
688
|
-
var CHAIN_MAP = {
|
|
689
|
-
gnosis,
|
|
690
|
-
sepolia
|
|
691
|
-
};
|
|
692
|
-
var CHAIN = CHAIN_MAP[NETWORK_NAME];
|
|
693
|
-
|
|
694
|
-
// src/sdk/pimlico-utils.ts
|
|
695
872
|
import { generatePrivateKey } from "viem/accounts";
|
|
873
|
+
var init_pimlico_utils = __esm({
|
|
874
|
+
"src/sdk/pimlico-utils.ts"() {
|
|
875
|
+
"use strict";
|
|
876
|
+
init_esm_shims();
|
|
877
|
+
init_constants3();
|
|
878
|
+
}
|
|
879
|
+
});
|
|
696
880
|
|
|
697
|
-
// src/sdk/
|
|
698
|
-
import {
|
|
881
|
+
// src/sdk/smart-agent.ts
|
|
882
|
+
import { toHex as toHex2 } from "viem";
|
|
883
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
884
|
+
var init_smart_agent = __esm({
|
|
885
|
+
"src/sdk/smart-agent.ts"() {
|
|
886
|
+
"use strict";
|
|
887
|
+
init_esm_shims();
|
|
888
|
+
init_pimlico_utils();
|
|
889
|
+
init_constants();
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
// src/sdk/file-encryption.ts
|
|
894
|
+
import { generateRandomBytes } from "@fileverse/crypto/utils";
|
|
895
|
+
var init_file_encryption = __esm({
|
|
896
|
+
"src/sdk/file-encryption.ts"() {
|
|
897
|
+
"use strict";
|
|
898
|
+
init_esm_shims();
|
|
899
|
+
}
|
|
900
|
+
});
|
|
699
901
|
|
|
700
902
|
// src/sdk/file-utils.ts
|
|
701
903
|
import { getArgon2idHash } from "@fileverse/crypto/argon";
|
|
@@ -705,246 +907,419 @@ import { secretBoxEncrypt } from "@fileverse/crypto/nacl";
|
|
|
705
907
|
import hkdf from "futoin-hkdf";
|
|
706
908
|
import tweetnacl from "tweetnacl";
|
|
707
909
|
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
708
|
-
|
|
709
|
-
// src/sdk/file-encryption.ts
|
|
710
|
-
import { generateRandomBytes } from "@fileverse/crypto/utils";
|
|
711
|
-
|
|
712
|
-
// src/sdk/file-utils.ts
|
|
713
910
|
import { toAESKey, aesEncrypt } from "@fileverse/crypto/webcrypto";
|
|
714
911
|
import axios from "axios";
|
|
715
912
|
import { encodeFunctionData, parseEventLogs } from "viem";
|
|
913
|
+
var init_file_utils = __esm({
|
|
914
|
+
"src/sdk/file-utils.ts"() {
|
|
915
|
+
"use strict";
|
|
916
|
+
init_esm_shims();
|
|
917
|
+
init_file_encryption();
|
|
918
|
+
init_constants3();
|
|
919
|
+
}
|
|
920
|
+
});
|
|
716
921
|
|
|
717
922
|
// src/sdk/file-manager.ts
|
|
923
|
+
import { fromUint8Array as fromUint8Array2, toUint8Array as toUint8Array2 } from "js-base64";
|
|
718
924
|
import { generateAESKey, exportAESKey } from "@fileverse/crypto/webcrypto";
|
|
719
925
|
import { markdownToYjs } from "@fileverse/content-processor";
|
|
926
|
+
var init_file_manager = __esm({
|
|
927
|
+
"src/sdk/file-manager.ts"() {
|
|
928
|
+
"use strict";
|
|
929
|
+
init_esm_shims();
|
|
930
|
+
init_file_utils();
|
|
931
|
+
init_constants();
|
|
932
|
+
init_constants3();
|
|
933
|
+
init_infra();
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
// src/domain/portal/publish.ts
|
|
938
|
+
import { fromUint8Array as fromUint8Array3, toUint8Array as toUint8Array3 } from "js-base64";
|
|
939
|
+
import { stringToBytes } from "viem";
|
|
940
|
+
import { deriveHKDFKey } from "@fileverse/crypto/kdf";
|
|
941
|
+
import { generateKeyPairFromSeed } from "@stablelib/ed25519";
|
|
942
|
+
import * as ucans2 from "@ucans/ucans";
|
|
943
|
+
var init_publish = __esm({
|
|
944
|
+
"src/domain/portal/publish.ts"() {
|
|
945
|
+
"use strict";
|
|
946
|
+
init_esm_shims();
|
|
947
|
+
init_models();
|
|
948
|
+
init_infra();
|
|
949
|
+
init_key_store();
|
|
950
|
+
init_auth_token_provider();
|
|
951
|
+
init_smart_agent();
|
|
952
|
+
init_file_manager();
|
|
953
|
+
init_config();
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
// src/domain/portal/savePortal.ts
|
|
958
|
+
var init_savePortal = __esm({
|
|
959
|
+
"src/domain/portal/savePortal.ts"() {
|
|
960
|
+
"use strict";
|
|
961
|
+
init_esm_shims();
|
|
962
|
+
init_models();
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
// src/domain/portal/saveApiKey.ts
|
|
967
|
+
var init_saveApiKey = __esm({
|
|
968
|
+
"src/domain/portal/saveApiKey.ts"() {
|
|
969
|
+
"use strict";
|
|
970
|
+
init_esm_shims();
|
|
971
|
+
init_models();
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
// src/domain/portal/removeApiKey.ts
|
|
976
|
+
var init_removeApiKey = __esm({
|
|
977
|
+
"src/domain/portal/removeApiKey.ts"() {
|
|
978
|
+
"use strict";
|
|
979
|
+
init_esm_shims();
|
|
980
|
+
init_models();
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
// src/domain/portal/index.ts
|
|
985
|
+
var init_portal = __esm({
|
|
986
|
+
"src/domain/portal/index.ts"() {
|
|
987
|
+
"use strict";
|
|
988
|
+
init_esm_shims();
|
|
989
|
+
init_publish();
|
|
990
|
+
init_savePortal();
|
|
991
|
+
init_saveApiKey();
|
|
992
|
+
init_removeApiKey();
|
|
993
|
+
}
|
|
994
|
+
});
|
|
720
995
|
|
|
721
996
|
// src/errors/rate-limit.ts
|
|
722
997
|
import { HttpRequestError } from "viem";
|
|
998
|
+
var init_rate_limit = __esm({
|
|
999
|
+
"src/errors/rate-limit.ts"() {
|
|
1000
|
+
"use strict";
|
|
1001
|
+
init_esm_shims();
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
// src/infra/worker/eventProcessor.ts
|
|
1006
|
+
var init_eventProcessor = __esm({
|
|
1007
|
+
"src/infra/worker/eventProcessor.ts"() {
|
|
1008
|
+
"use strict";
|
|
1009
|
+
init_esm_shims();
|
|
1010
|
+
init_config();
|
|
1011
|
+
init_portal();
|
|
1012
|
+
init_models();
|
|
1013
|
+
init_infra();
|
|
1014
|
+
init_pimlico_utils();
|
|
1015
|
+
init_file_utils();
|
|
1016
|
+
init_constants3();
|
|
1017
|
+
init_rate_limit();
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
723
1020
|
|
|
724
1021
|
// src/infra/worker/worker.ts
|
|
725
|
-
var STALE_THRESHOLD_MS
|
|
1022
|
+
var STALE_THRESHOLD_MS;
|
|
1023
|
+
var init_worker = __esm({
|
|
1024
|
+
"src/infra/worker/worker.ts"() {
|
|
1025
|
+
"use strict";
|
|
1026
|
+
init_esm_shims();
|
|
1027
|
+
init_infra();
|
|
1028
|
+
init_eventProcessor();
|
|
1029
|
+
init_workerSignal();
|
|
1030
|
+
init_models();
|
|
1031
|
+
init_rate_limit();
|
|
1032
|
+
STALE_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
|
|
1036
|
+
// src/infra/worker/index.ts
|
|
1037
|
+
var init_worker2 = __esm({
|
|
1038
|
+
"src/infra/worker/index.ts"() {
|
|
1039
|
+
"use strict";
|
|
1040
|
+
init_esm_shims();
|
|
1041
|
+
init_worker();
|
|
1042
|
+
init_workerSignal();
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
726
1045
|
|
|
727
1046
|
// src/appWorker.ts
|
|
728
|
-
var worker = null;
|
|
729
1047
|
async function closeWorker() {
|
|
730
1048
|
if (worker) {
|
|
731
1049
|
await worker.close();
|
|
732
1050
|
worker = null;
|
|
733
1051
|
}
|
|
734
1052
|
}
|
|
1053
|
+
var worker;
|
|
1054
|
+
var init_appWorker = __esm({
|
|
1055
|
+
"src/appWorker.ts"() {
|
|
1056
|
+
"use strict";
|
|
1057
|
+
init_esm_shims();
|
|
1058
|
+
init_worker2();
|
|
1059
|
+
worker = null;
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
735
1062
|
|
|
736
1063
|
// src/infra/reporter.ts
|
|
737
|
-
var Reporter
|
|
738
|
-
|
|
739
|
-
|
|
1064
|
+
var Reporter, reporter_default;
|
|
1065
|
+
var init_reporter = __esm({
|
|
1066
|
+
"src/infra/reporter.ts"() {
|
|
1067
|
+
"use strict";
|
|
1068
|
+
init_esm_shims();
|
|
1069
|
+
Reporter = class {
|
|
1070
|
+
async reportError(message) {
|
|
1071
|
+
console.error("Error reported:", message);
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
reporter_default = new Reporter();
|
|
740
1075
|
}
|
|
741
|
-
};
|
|
742
|
-
var reporter_default = new Reporter();
|
|
1076
|
+
});
|
|
743
1077
|
|
|
744
|
-
// src/infra/
|
|
745
|
-
var
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
logger.info(`SQLite database connected: ${dbPath}`);
|
|
755
|
-
}
|
|
756
|
-
async select(sql, params = []) {
|
|
757
|
-
const stmt = this.db.prepare(sql);
|
|
758
|
-
return stmt.all(params);
|
|
759
|
-
}
|
|
760
|
-
async selectOne(sql, params = []) {
|
|
761
|
-
const stmt = this.db.prepare(sql);
|
|
762
|
-
return stmt.get(params);
|
|
763
|
-
}
|
|
764
|
-
async execute(sql, params = []) {
|
|
765
|
-
const stmt = this.db.prepare(sql);
|
|
766
|
-
const result = stmt.run(params);
|
|
767
|
-
return {
|
|
768
|
-
changes: result.changes,
|
|
769
|
-
lastInsertRowid: result.lastInsertRowid
|
|
770
|
-
};
|
|
1078
|
+
// src/infra/index.ts
|
|
1079
|
+
var init_infra = __esm({
|
|
1080
|
+
"src/infra/index.ts"() {
|
|
1081
|
+
"use strict";
|
|
1082
|
+
init_esm_shims();
|
|
1083
|
+
init_logger();
|
|
1084
|
+
init_asyncHandler();
|
|
1085
|
+
init_appWorker();
|
|
1086
|
+
init_database();
|
|
1087
|
+
init_reporter();
|
|
771
1088
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
// src/infra/database/adapters/sql-compat.ts
|
|
1092
|
+
function sqliteToPostgres(sql) {
|
|
1093
|
+
let result = "";
|
|
1094
|
+
let paramIndex = 0;
|
|
1095
|
+
let inString = false;
|
|
1096
|
+
for (let i = 0; i < sql.length; i++) {
|
|
1097
|
+
const ch = sql[i];
|
|
1098
|
+
if (ch === "'") {
|
|
1099
|
+
if (inString && i + 1 < sql.length && sql[i + 1] === "'") {
|
|
1100
|
+
result += "''";
|
|
1101
|
+
i++;
|
|
1102
|
+
continue;
|
|
1103
|
+
}
|
|
1104
|
+
inString = !inString;
|
|
1105
|
+
result += ch;
|
|
1106
|
+
} else if (ch === "?" && !inString) {
|
|
1107
|
+
paramIndex++;
|
|
1108
|
+
result += `$${paramIndex}`;
|
|
1109
|
+
} else {
|
|
1110
|
+
result += ch;
|
|
781
1111
|
}
|
|
782
1112
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
1113
|
+
return result;
|
|
1114
|
+
}
|
|
1115
|
+
var init_sql_compat = __esm({
|
|
1116
|
+
"src/infra/database/adapters/sql-compat.ts"() {
|
|
1117
|
+
"use strict";
|
|
1118
|
+
init_esm_shims();
|
|
789
1119
|
}
|
|
790
|
-
};
|
|
1120
|
+
});
|
|
791
1121
|
|
|
792
|
-
// src/infra/database/adapters/
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
isdeleted: "isDeleted",
|
|
801
|
-
onchainfileid: "onChainFileId",
|
|
802
|
-
portaladdress: "portalAddress",
|
|
803
|
-
createdat: "createdAt",
|
|
804
|
-
updatedat: "updatedAt",
|
|
805
|
-
linkkey: "linkKey",
|
|
806
|
-
linkkeynonce: "linkKeyNonce",
|
|
807
|
-
commentkey: "commentKey",
|
|
808
|
-
portalseed: "portalSeed",
|
|
809
|
-
owneraddress: "ownerAddress",
|
|
810
|
-
apikeyseed: "apiKeySeed",
|
|
811
|
-
collaboratoraddress: "collaboratorAddress",
|
|
812
|
-
fileid: "fileId",
|
|
813
|
-
retrycount: "retryCount",
|
|
814
|
-
lasterror: "lastError",
|
|
815
|
-
lockedat: "lockedAt",
|
|
816
|
-
nextretryat: "nextRetryAt",
|
|
817
|
-
userophash: "userOpHash",
|
|
818
|
-
pendingpayload: "pendingPayload",
|
|
819
|
-
folderid: "folderId",
|
|
820
|
-
folderref: "folderRef",
|
|
821
|
-
foldername: "folderName",
|
|
822
|
-
metadataipfshash: "metadataIPFSHash",
|
|
823
|
-
contentipfshash: "contentIPFSHash",
|
|
824
|
-
lasttransactionhash: "lastTransactionHash",
|
|
825
|
-
lasttransactionblocknumber: "lastTransactionBlockNumber",
|
|
826
|
-
lasttransactionblocktimestamp: "lastTransactionBlockTimestamp",
|
|
827
|
-
created_at: "created_at",
|
|
828
|
-
updated_at: "updated_at"
|
|
829
|
-
};
|
|
830
|
-
function translateParams(sql) {
|
|
831
|
-
let idx = 0;
|
|
832
|
-
return sql.replace(/\?/g, () => `$${++idx}`);
|
|
833
|
-
}
|
|
834
|
-
function mapRow(row) {
|
|
835
|
-
const mapped = {};
|
|
836
|
-
for (const [key, value] of Object.entries(row)) {
|
|
837
|
-
const mappedKey = COLUMN_NAME_MAP[key] ?? key;
|
|
838
|
-
mapped[mappedKey] = value instanceof Date ? value.toISOString() : value;
|
|
1122
|
+
// src/infra/database/adapters/postgres-adapter.ts
|
|
1123
|
+
var postgres_adapter_exports = {};
|
|
1124
|
+
__export(postgres_adapter_exports, {
|
|
1125
|
+
PostgresAdapter: () => PostgresAdapter
|
|
1126
|
+
});
|
|
1127
|
+
async function getPg() {
|
|
1128
|
+
if (!pgModule) {
|
|
1129
|
+
pgModule = await import("pg");
|
|
839
1130
|
}
|
|
840
|
-
return
|
|
1131
|
+
return pgModule;
|
|
841
1132
|
}
|
|
842
|
-
var
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1133
|
+
var pgModule, PostgresAdapter;
|
|
1134
|
+
var init_postgres_adapter = __esm({
|
|
1135
|
+
"src/infra/database/adapters/postgres-adapter.ts"() {
|
|
1136
|
+
"use strict";
|
|
1137
|
+
init_esm_shims();
|
|
1138
|
+
init_sql_compat();
|
|
1139
|
+
init_infra();
|
|
1140
|
+
pgModule = null;
|
|
1141
|
+
PostgresAdapter = class {
|
|
1142
|
+
pool = null;
|
|
1143
|
+
connectionUrl;
|
|
1144
|
+
connected = false;
|
|
1145
|
+
dialect = "postgres";
|
|
1146
|
+
constructor(connectionUrl) {
|
|
1147
|
+
this.connectionUrl = connectionUrl;
|
|
1148
|
+
}
|
|
1149
|
+
async getPool() {
|
|
1150
|
+
if (!this.pool) {
|
|
1151
|
+
const pg = await getPg();
|
|
1152
|
+
this.pool = new pg.default.Pool({
|
|
1153
|
+
connectionString: this.connectionUrl,
|
|
1154
|
+
max: 10,
|
|
1155
|
+
ssl: this.connectionUrl.includes("sslmode=require") || this.connectionUrl.includes("amazonaws.com") || this.connectionUrl.includes("heroku") ? { rejectUnauthorized: false } : void 0
|
|
1156
|
+
});
|
|
1157
|
+
const client = await this.pool.connect();
|
|
1158
|
+
client.release();
|
|
1159
|
+
this.connected = true;
|
|
1160
|
+
logger.info("PostgreSQL database connected");
|
|
1161
|
+
}
|
|
1162
|
+
return this.pool;
|
|
1163
|
+
}
|
|
1164
|
+
async select(sql, params = []) {
|
|
1165
|
+
const pool = await this.getPool();
|
|
1166
|
+
const pgSql = sqliteToPostgres(sql);
|
|
1167
|
+
const result = await pool.query(pgSql, params);
|
|
1168
|
+
return result.rows;
|
|
1169
|
+
}
|
|
1170
|
+
async selectOne(sql, params = []) {
|
|
1171
|
+
const pool = await this.getPool();
|
|
1172
|
+
const pgSql = sqliteToPostgres(sql);
|
|
1173
|
+
const result = await pool.query(pgSql, params);
|
|
1174
|
+
return result.rows[0] ?? void 0;
|
|
1175
|
+
}
|
|
1176
|
+
async execute(sql, params = []) {
|
|
1177
|
+
const pool = await this.getPool();
|
|
1178
|
+
const pgSql = sqliteToPostgres(sql);
|
|
1179
|
+
const result = await pool.query(pgSql, params);
|
|
1180
|
+
return {
|
|
1181
|
+
changes: result.rowCount ?? 0,
|
|
1182
|
+
lastInsertRowid: 0
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
async transaction(callback) {
|
|
1186
|
+
const pool = await this.getPool();
|
|
1187
|
+
const client = await pool.connect();
|
|
1188
|
+
try {
|
|
1189
|
+
await client.query("BEGIN");
|
|
1190
|
+
const result = await callback();
|
|
1191
|
+
await client.query("COMMIT");
|
|
1192
|
+
return result;
|
|
1193
|
+
} catch (error) {
|
|
1194
|
+
await client.query("ROLLBACK");
|
|
1195
|
+
throw error;
|
|
1196
|
+
} finally {
|
|
1197
|
+
client.release();
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
async exec(sql) {
|
|
1201
|
+
const pool = await this.getPool();
|
|
1202
|
+
await pool.query(sql);
|
|
1203
|
+
}
|
|
1204
|
+
async close() {
|
|
1205
|
+
if (this.pool) {
|
|
1206
|
+
await this.pool.end();
|
|
1207
|
+
this.pool = null;
|
|
1208
|
+
this.connected = false;
|
|
1209
|
+
logger.info("Database connection closed");
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
isConnected() {
|
|
1213
|
+
return this.connected;
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
921
1216
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1217
|
+
});
|
|
1218
|
+
|
|
1219
|
+
// src/infra/database/adapters/sqlite-adapter.ts
|
|
1220
|
+
var sqlite_adapter_exports = {};
|
|
1221
|
+
__export(sqlite_adapter_exports, {
|
|
1222
|
+
SqliteAdapter: () => SqliteAdapter
|
|
1223
|
+
});
|
|
1224
|
+
import Database from "better-sqlite3";
|
|
1225
|
+
var SqliteAdapter;
|
|
1226
|
+
var init_sqlite_adapter = __esm({
|
|
1227
|
+
"src/infra/database/adapters/sqlite-adapter.ts"() {
|
|
1228
|
+
"use strict";
|
|
1229
|
+
init_esm_shims();
|
|
1230
|
+
init_infra();
|
|
1231
|
+
SqliteAdapter = class {
|
|
1232
|
+
constructor(dbPath) {
|
|
1233
|
+
this.dbPath = dbPath;
|
|
1234
|
+
}
|
|
1235
|
+
db = null;
|
|
1236
|
+
dialect = "sqlite";
|
|
1237
|
+
getDb() {
|
|
1238
|
+
if (!this.db) {
|
|
1239
|
+
this.db = new Database(this.dbPath);
|
|
1240
|
+
this.db.pragma("journal_mode = WAL");
|
|
1241
|
+
this.db.pragma("foreign_keys = ON");
|
|
1242
|
+
this.db.prepare("SELECT 1").get();
|
|
1243
|
+
logger.info(`SQLite database connected: ${this.dbPath}`);
|
|
1244
|
+
}
|
|
1245
|
+
return this.db;
|
|
1246
|
+
}
|
|
1247
|
+
async select(sql, params = []) {
|
|
1248
|
+
const stmt = this.getDb().prepare(sql);
|
|
1249
|
+
return stmt.all(params);
|
|
1250
|
+
}
|
|
1251
|
+
async selectOne(sql, params = []) {
|
|
1252
|
+
const stmt = this.getDb().prepare(sql);
|
|
1253
|
+
return stmt.get(params);
|
|
1254
|
+
}
|
|
1255
|
+
async execute(sql, params = []) {
|
|
1256
|
+
const stmt = this.getDb().prepare(sql);
|
|
1257
|
+
const result = stmt.run(params);
|
|
1258
|
+
return {
|
|
1259
|
+
changes: result.changes,
|
|
1260
|
+
lastInsertRowid: result.lastInsertRowid
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
async transaction(callback) {
|
|
1264
|
+
const db = this.getDb();
|
|
1265
|
+
const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1266
|
+
db.exec(`SAVEPOINT ${savepointName}`);
|
|
1267
|
+
try {
|
|
1268
|
+
const result = await callback();
|
|
1269
|
+
db.exec(`RELEASE ${savepointName}`);
|
|
1270
|
+
return result;
|
|
1271
|
+
} catch (error) {
|
|
1272
|
+
db.exec(`ROLLBACK TO ${savepointName}`);
|
|
1273
|
+
db.exec(`RELEASE ${savepointName}`);
|
|
1274
|
+
throw error;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
async exec(sql) {
|
|
1278
|
+
this.getDb().exec(sql);
|
|
1279
|
+
}
|
|
1280
|
+
async close() {
|
|
1281
|
+
if (this.db) {
|
|
1282
|
+
this.db.close();
|
|
1283
|
+
this.db = null;
|
|
1284
|
+
logger.info("Database connection closed");
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
isConnected() {
|
|
1288
|
+
return this.db !== null && this.db.open;
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
925
1291
|
}
|
|
926
|
-
};
|
|
1292
|
+
});
|
|
927
1293
|
|
|
928
1294
|
// src/infra/database/connection.ts
|
|
929
|
-
|
|
930
|
-
|
|
1295
|
+
import path3 from "path";
|
|
1296
|
+
import fs2 from "fs";
|
|
1297
|
+
async function initializeAdapter() {
|
|
931
1298
|
if (adapter) return adapter;
|
|
932
|
-
const databaseUrl =
|
|
933
|
-
const dbPath =
|
|
1299
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
1300
|
+
const dbPath = process.env.DB_PATH;
|
|
934
1301
|
if (databaseUrl) {
|
|
935
|
-
|
|
1302
|
+
const { PostgresAdapter: PostgresAdapter2 } = await Promise.resolve().then(() => (init_postgres_adapter(), postgres_adapter_exports));
|
|
1303
|
+
adapter = new PostgresAdapter2(databaseUrl);
|
|
1304
|
+
logger.info("Using PostgreSQL adapter");
|
|
936
1305
|
} else if (dbPath) {
|
|
937
|
-
|
|
1306
|
+
const dbDir = path3.dirname(dbPath.trim());
|
|
1307
|
+
if (!fs2.existsSync(dbDir)) {
|
|
1308
|
+
fs2.mkdirSync(dbDir, { recursive: true });
|
|
1309
|
+
}
|
|
1310
|
+
const { SqliteAdapter: SqliteAdapter2 } = await Promise.resolve().then(() => (init_sqlite_adapter(), sqlite_adapter_exports));
|
|
1311
|
+
adapter = new SqliteAdapter2(dbPath);
|
|
1312
|
+
logger.info("Using SQLite adapter");
|
|
938
1313
|
} else {
|
|
939
|
-
throw new Error(
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
"No database configured. Set DATABASE_URL (PostgreSQL) or DB_PATH (SQLite)."
|
|
1316
|
+
);
|
|
940
1317
|
}
|
|
941
1318
|
return adapter;
|
|
942
1319
|
}
|
|
943
|
-
function
|
|
1320
|
+
async function getAdapter() {
|
|
944
1321
|
if (!adapter) {
|
|
945
|
-
|
|
946
|
-
"Database adapter not initialized. Call getAdapter() at startup first."
|
|
947
|
-
);
|
|
1322
|
+
return initializeAdapter();
|
|
948
1323
|
}
|
|
949
1324
|
return adapter;
|
|
950
1325
|
}
|
|
@@ -954,8 +1329,26 @@ async function closeAdapter() {
|
|
|
954
1329
|
adapter = null;
|
|
955
1330
|
}
|
|
956
1331
|
}
|
|
1332
|
+
var adapter;
|
|
1333
|
+
var init_connection = __esm({
|
|
1334
|
+
"src/infra/database/connection.ts"() {
|
|
1335
|
+
"use strict";
|
|
1336
|
+
init_esm_shims();
|
|
1337
|
+
init_infra();
|
|
1338
|
+
adapter = null;
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
// src/commands/index.ts
|
|
1343
|
+
init_esm_shims();
|
|
1344
|
+
init_config();
|
|
1345
|
+
init_logger();
|
|
1346
|
+
import { Command as Command9 } from "commander";
|
|
957
1347
|
|
|
958
1348
|
// src/infra/database/migrations/index.ts
|
|
1349
|
+
init_esm_shims();
|
|
1350
|
+
init_connection();
|
|
1351
|
+
init_infra();
|
|
959
1352
|
var STABLE_SCHEMA = `
|
|
960
1353
|
CREATE TABLE IF NOT EXISTS files (
|
|
961
1354
|
_id TEXT PRIMARY KEY,
|
|
@@ -1040,16 +1433,20 @@ CREATE INDEX IF NOT EXISTS idx_folders_folderRef ON folders(folderRef);
|
|
|
1040
1433
|
CREATE INDEX IF NOT EXISTS idx_folders_created_at ON folders(created_at);
|
|
1041
1434
|
`;
|
|
1042
1435
|
async function runMigrations() {
|
|
1043
|
-
const adapter2 =
|
|
1436
|
+
const adapter2 = await getAdapter();
|
|
1044
1437
|
await adapter2.exec(STABLE_SCHEMA);
|
|
1045
1438
|
logger.debug("Database schema ready");
|
|
1046
1439
|
}
|
|
1047
1440
|
|
|
1048
1441
|
// src/commands/listCommand.ts
|
|
1442
|
+
init_esm_shims();
|
|
1049
1443
|
import { Command } from "commander";
|
|
1050
1444
|
import Table from "cli-table3";
|
|
1051
1445
|
|
|
1052
1446
|
// src/domain/file/index.ts
|
|
1447
|
+
init_esm_shims();
|
|
1448
|
+
init_models();
|
|
1449
|
+
init_constants2();
|
|
1053
1450
|
import { generate } from "short-uuid";
|
|
1054
1451
|
async function listFiles(params) {
|
|
1055
1452
|
const { limit, skip, portalAddress } = params;
|
|
@@ -1160,6 +1557,7 @@ var deleteFile = async (ddocId, portalAddress) => {
|
|
|
1160
1557
|
};
|
|
1161
1558
|
|
|
1162
1559
|
// src/commands/utils/util.ts
|
|
1560
|
+
init_esm_shims();
|
|
1163
1561
|
var columnNames = {
|
|
1164
1562
|
index: "#",
|
|
1165
1563
|
ddocId: "DDoc ID",
|
|
@@ -1236,12 +1634,15 @@ After setup, you can use ddctl commands.
|
|
|
1236
1634
|
}
|
|
1237
1635
|
|
|
1238
1636
|
// src/commands/listCommand.ts
|
|
1637
|
+
init_config();
|
|
1638
|
+
init_models();
|
|
1239
1639
|
var listCommand = new Command().name("list").description("List all ddocs").option("-l, --limit <number>", "Limit the number of results", parseInt).option("-s, --skip <number>", "Skip the first N results", parseInt).action(async (options) => {
|
|
1240
1640
|
try {
|
|
1241
1641
|
const runtimeConfig = getRuntimeConfig();
|
|
1242
1642
|
const apiKey = runtimeConfig.API_KEY;
|
|
1243
1643
|
validateApiKey(apiKey);
|
|
1244
|
-
const
|
|
1644
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1645
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1245
1646
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1246
1647
|
const params = {
|
|
1247
1648
|
limit: options.limit,
|
|
@@ -1303,14 +1704,18 @@ Found ${result.total} ddoc(s):
|
|
|
1303
1704
|
});
|
|
1304
1705
|
|
|
1305
1706
|
// src/commands/getCommand.ts
|
|
1707
|
+
init_esm_shims();
|
|
1306
1708
|
import { Command as Command2 } from "commander";
|
|
1307
1709
|
import Table2 from "cli-table3";
|
|
1710
|
+
init_config();
|
|
1711
|
+
init_models();
|
|
1308
1712
|
var getCommand = new Command2().name("get").description("Get a ddoc by its ID").argument("<ddocId>", "The ddoc ID to retrieve").action(async (ddocId) => {
|
|
1309
1713
|
try {
|
|
1310
1714
|
const runtimeConfig = getRuntimeConfig();
|
|
1311
1715
|
const apiKey = runtimeConfig.API_KEY;
|
|
1312
1716
|
validateApiKey(apiKey);
|
|
1313
|
-
const
|
|
1717
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1718
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1314
1719
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1315
1720
|
const file = await getFile(ddocId, portalAddress);
|
|
1316
1721
|
if (!file) {
|
|
@@ -1365,26 +1770,30 @@ Link: ${file.link}
|
|
|
1365
1770
|
});
|
|
1366
1771
|
|
|
1367
1772
|
// src/commands/createCommand.ts
|
|
1773
|
+
init_esm_shims();
|
|
1368
1774
|
import { Command as Command3 } from "commander";
|
|
1369
|
-
import * as
|
|
1370
|
-
import * as
|
|
1775
|
+
import * as fs3 from "fs";
|
|
1776
|
+
import * as path4 from "path";
|
|
1371
1777
|
import Table3 from "cli-table3";
|
|
1778
|
+
init_config();
|
|
1779
|
+
init_models();
|
|
1372
1780
|
var createCommand = new Command3().name("create").description("Create a new ddoc from a file").argument("<filepath>", "Path to the file to create ddoc from").action(async (filepath) => {
|
|
1373
1781
|
try {
|
|
1374
|
-
if (!
|
|
1782
|
+
if (!fs3.existsSync(filepath)) {
|
|
1375
1783
|
throw new Error(`File not found: ${filepath}`);
|
|
1376
1784
|
}
|
|
1377
1785
|
const runtimeConfig = getRuntimeConfig();
|
|
1378
1786
|
const apiKey = runtimeConfig.API_KEY;
|
|
1379
1787
|
validateApiKey(apiKey);
|
|
1380
|
-
const
|
|
1788
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1789
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1381
1790
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1382
|
-
const content =
|
|
1791
|
+
const content = fs3.readFileSync(filepath, "utf-8");
|
|
1383
1792
|
if (!content || content.trim().length === 0) {
|
|
1384
1793
|
console.error("Error creating ddoc: File content cannot be empty. Add some content to the file and try again.");
|
|
1385
1794
|
process.exit(1);
|
|
1386
1795
|
}
|
|
1387
|
-
const basename3 =
|
|
1796
|
+
const basename3 = path4.basename(filepath);
|
|
1388
1797
|
const lastDotIndex = basename3.lastIndexOf(".");
|
|
1389
1798
|
const title = lastDotIndex > 0 ? basename3.substring(0, lastDotIndex) : basename3;
|
|
1390
1799
|
const file = await createFile({ title, content, portalAddress });
|
|
@@ -1428,12 +1837,15 @@ var createCommand = new Command3().name("create").description("Create a new ddoc
|
|
|
1428
1837
|
});
|
|
1429
1838
|
|
|
1430
1839
|
// src/commands/updateCommand.ts
|
|
1431
|
-
|
|
1432
|
-
import * as
|
|
1840
|
+
init_esm_shims();
|
|
1841
|
+
import * as fs4 from "fs";
|
|
1842
|
+
import * as path5 from "path";
|
|
1433
1843
|
import * as os2 from "os";
|
|
1434
1844
|
import { Command as Command4 } from "commander";
|
|
1435
1845
|
import { spawnSync } from "child_process";
|
|
1436
1846
|
import Table4 from "cli-table3";
|
|
1847
|
+
init_models();
|
|
1848
|
+
init_config();
|
|
1437
1849
|
function showTable(updatedFile) {
|
|
1438
1850
|
const table = new Table4({
|
|
1439
1851
|
head: [
|
|
@@ -1473,7 +1885,8 @@ var updateCommand = new Command4().name("update").description("Update an existin
|
|
|
1473
1885
|
const runtimeConfig = getRuntimeConfig();
|
|
1474
1886
|
const apiKey = runtimeConfig.API_KEY;
|
|
1475
1887
|
validateApiKey(apiKey);
|
|
1476
|
-
const
|
|
1888
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1889
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1477
1890
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1478
1891
|
const file = await getFile(ddocId, portalAddress);
|
|
1479
1892
|
if (!file) {
|
|
@@ -1481,11 +1894,13 @@ var updateCommand = new Command4().name("update").description("Update an existin
|
|
|
1481
1894
|
}
|
|
1482
1895
|
const filePath = options?.file ?? "";
|
|
1483
1896
|
if (filePath) {
|
|
1484
|
-
const content =
|
|
1897
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
1485
1898
|
if (!content || content.trim().length === 0) {
|
|
1486
1899
|
throw new Error(`file content cannot be empty`);
|
|
1487
1900
|
}
|
|
1488
|
-
const
|
|
1901
|
+
const basename3 = path5.basename(filePath);
|
|
1902
|
+
const lastDotIndex = basename3.lastIndexOf(".");
|
|
1903
|
+
const title = lastDotIndex > 0 ? basename3.substring(0, lastDotIndex) : basename3;
|
|
1489
1904
|
const payload = {
|
|
1490
1905
|
title,
|
|
1491
1906
|
content
|
|
@@ -1495,15 +1910,15 @@ var updateCommand = new Command4().name("update").description("Update an existin
|
|
|
1495
1910
|
showTable(updatedFile);
|
|
1496
1911
|
return;
|
|
1497
1912
|
}
|
|
1498
|
-
const tmpFilePath =
|
|
1499
|
-
|
|
1913
|
+
const tmpFilePath = path5.join(os2.tmpdir(), `tmp-${ddocId}-${Date.now()}.txt`);
|
|
1914
|
+
fs4.writeFileSync(tmpFilePath, file.content);
|
|
1500
1915
|
const editor = process.env.EDITOR || "vi";
|
|
1501
1916
|
const result = spawnSync(editor, [tmpFilePath], { stdio: "inherit" });
|
|
1502
1917
|
if (result.status === 0) {
|
|
1503
|
-
const newContent =
|
|
1918
|
+
const newContent = fs4.readFileSync(tmpFilePath, "utf-8");
|
|
1504
1919
|
if (newContent === file.content) {
|
|
1505
1920
|
console.log(`No changes made. Update cancelled.`);
|
|
1506
|
-
|
|
1921
|
+
fs4.unlinkSync(tmpFilePath);
|
|
1507
1922
|
return;
|
|
1508
1923
|
}
|
|
1509
1924
|
const payload = {
|
|
@@ -1515,7 +1930,7 @@ var updateCommand = new Command4().name("update").description("Update an existin
|
|
|
1515
1930
|
console.log("\n\u2713 Ddoc updated successfully!\n");
|
|
1516
1931
|
showTable(updatedFile);
|
|
1517
1932
|
}
|
|
1518
|
-
|
|
1933
|
+
fs4.unlinkSync(tmpFilePath);
|
|
1519
1934
|
} catch (error) {
|
|
1520
1935
|
console.error("Error updating ddoc:", error.message);
|
|
1521
1936
|
throw error;
|
|
@@ -1523,13 +1938,17 @@ var updateCommand = new Command4().name("update").description("Update an existin
|
|
|
1523
1938
|
});
|
|
1524
1939
|
|
|
1525
1940
|
// src/commands/deleteCommand.ts
|
|
1941
|
+
init_esm_shims();
|
|
1526
1942
|
import { Command as Command5 } from "commander";
|
|
1943
|
+
init_config();
|
|
1944
|
+
init_models();
|
|
1527
1945
|
var deleteCommand = new Command5().name("delete").description("Delete one or more ddocs by their IDs").argument("<ddocIds...>", "One or more ddoc IDs to delete (space-separated)").action(async (ddocIds) => {
|
|
1528
1946
|
try {
|
|
1529
1947
|
const runtimeConfig = getRuntimeConfig();
|
|
1530
1948
|
const apiKey = runtimeConfig.API_KEY;
|
|
1531
1949
|
validateApiKey(apiKey);
|
|
1532
|
-
const
|
|
1950
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1951
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1533
1952
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1534
1953
|
for (const ddocId of ddocIds) {
|
|
1535
1954
|
try {
|
|
@@ -1546,14 +1965,18 @@ var deleteCommand = new Command5().name("delete").description("Delete one or mor
|
|
|
1546
1965
|
});
|
|
1547
1966
|
|
|
1548
1967
|
// src/commands/downloadCommand.ts
|
|
1968
|
+
init_esm_shims();
|
|
1549
1969
|
import { Command as Command6 } from "commander";
|
|
1550
|
-
import * as
|
|
1970
|
+
import * as fs5 from "fs";
|
|
1971
|
+
init_config();
|
|
1972
|
+
init_models();
|
|
1551
1973
|
var downloadCommand = new Command6().name("download").description("Download a ddoc to a local file").argument("<ddocId>", "The ddoc ID to download").option("-o, --output <filename>", "Output filename (only supports markdown)").action(async (ddocId, options) => {
|
|
1552
1974
|
try {
|
|
1553
1975
|
const runtimeConfig = getRuntimeConfig();
|
|
1554
1976
|
const apiKey = runtimeConfig.API_KEY;
|
|
1555
1977
|
validateApiKey(apiKey);
|
|
1556
|
-
const
|
|
1978
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
1979
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1557
1980
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1558
1981
|
const file = await getFile(ddocId, portalAddress);
|
|
1559
1982
|
if (!file) {
|
|
@@ -1564,7 +1987,7 @@ var downloadCommand = new Command6().name("download").description("Download a dd
|
|
|
1564
1987
|
if (options.output) {
|
|
1565
1988
|
outputFilename = options.output.endsWith(".md") ? options.output : `${options.output}.md`;
|
|
1566
1989
|
}
|
|
1567
|
-
|
|
1990
|
+
fs5.writeFileSync(outputFilename, file.content, "utf-8");
|
|
1568
1991
|
console.log(`
|
|
1569
1992
|
\u2713 Ddoc downloaded successfully to: ${outputFilename}
|
|
1570
1993
|
`);
|
|
@@ -1575,13 +1998,17 @@ var downloadCommand = new Command6().name("download").description("Download a dd
|
|
|
1575
1998
|
});
|
|
1576
1999
|
|
|
1577
2000
|
// src/commands/viewCommand.ts
|
|
2001
|
+
init_esm_shims();
|
|
1578
2002
|
import { Command as Command7 } from "commander";
|
|
2003
|
+
init_config();
|
|
2004
|
+
init_models();
|
|
1579
2005
|
var viewCommand = new Command7().name("view").description("View content preview of a ddoc").argument("<ddocId>", "The ddoc ID to view").option("-n, --lines <number>", "Number of lines to preview (default: 10)", "10").action(async (ddocId, options) => {
|
|
1580
2006
|
try {
|
|
1581
2007
|
const runtimeConfig = getRuntimeConfig();
|
|
1582
2008
|
const apiKey = runtimeConfig.API_KEY;
|
|
1583
2009
|
validateApiKey(apiKey);
|
|
1584
|
-
const
|
|
2010
|
+
const apiKeyInfo = await ApiKeysModel.findByApiKey(apiKey);
|
|
2011
|
+
const portalAddress = apiKeyInfo?.portalAddress;
|
|
1585
2012
|
if (!portalAddress) throw new Error("Portal address is required");
|
|
1586
2013
|
const file = await getFile(ddocId, portalAddress);
|
|
1587
2014
|
if (!file) {
|
|
@@ -1619,6 +2046,8 @@ Showing ${linesToShow} of ${totalLines} line${totalLines === 1 ? "" : "s"}
|
|
|
1619
2046
|
});
|
|
1620
2047
|
|
|
1621
2048
|
// src/commands/eventsCommand.ts
|
|
2049
|
+
init_esm_shims();
|
|
2050
|
+
init_models();
|
|
1622
2051
|
import { Command as Command8 } from "commander";
|
|
1623
2052
|
import Table5 from "cli-table3";
|
|
1624
2053
|
var MAX_ERROR_LEN = 60;
|
|
@@ -1683,8 +2112,10 @@ eventsCommand.command("retry-all").description("Retry all failed events").action
|
|
|
1683
2112
|
});
|
|
1684
2113
|
|
|
1685
2114
|
// src/commands/index.ts
|
|
2115
|
+
init_infra();
|
|
1686
2116
|
logger.level = "error";
|
|
1687
|
-
|
|
2117
|
+
await runMigrations();
|
|
2118
|
+
var program = new Command9().name("ddctl").description("CLI tool to manage your ddocs").version("0.0.3").addHelpText("beforeAll", "\n").addHelpText("afterAll", "\n");
|
|
1688
2119
|
program.addCommand(listCommand);
|
|
1689
2120
|
program.addCommand(getCommand);
|
|
1690
2121
|
program.addCommand(createCommand);
|
|
@@ -1693,14 +2124,10 @@ program.addCommand(deleteCommand);
|
|
|
1693
2124
|
program.addCommand(downloadCommand);
|
|
1694
2125
|
program.addCommand(viewCommand);
|
|
1695
2126
|
program.addCommand(eventsCommand);
|
|
1696
|
-
(async () => {
|
|
1697
|
-
await getAdapter();
|
|
1698
|
-
await runMigrations();
|
|
1699
|
-
await program.parseAsync();
|
|
1700
|
-
})().then(async () => {
|
|
2127
|
+
program.parseAsync().then(async () => {
|
|
1701
2128
|
try {
|
|
1702
2129
|
await closeWorker();
|
|
1703
|
-
await
|
|
2130
|
+
await closeDatabase();
|
|
1704
2131
|
} catch (error) {
|
|
1705
2132
|
}
|
|
1706
2133
|
process.exit(0);
|