@axium/server 0.43.0 → 0.44.0
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/acl.d.ts +1 -1
- package/dist/acl.js +1 -1
- package/dist/api/admin.js +1 -1
- package/dist/api/images.js +1 -1
- package/dist/api/passkeys.js +1 -1
- package/dist/api/register.js +1 -1
- package/dist/api/session.js +1 -1
- package/dist/api/users.js +1 -1
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +2 -2
- package/dist/build.d.ts +19 -0
- package/dist/build.js +121 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +91 -2
- package/dist/db/cli.d.ts +1 -0
- package/dist/db/cli.js +392 -0
- package/dist/db/connection.d.ts +1 -1
- package/dist/{database.d.ts → db/index.d.ts} +4 -5
- package/dist/{database.js → db/index.js} +6 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/linking.d.ts +0 -1
- package/dist/linking.js +14 -42
- package/dist/main.d.ts +1 -1
- package/dist/main.js +515 -795
- package/package.json +16 -16
- package/patches/@sveltejs+kit+2.56.1.patch +43 -0
- package/routes/account/+page.svelte +1 -2
- package/routes/admin/users/[id]/+page.svelte +1 -2
- package/svelte.config.js +0 -33
package/dist/db/cli.js
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
53
|
+
import { Option, program } from 'commander';
|
|
54
|
+
import * as io from 'ioium/node';
|
|
55
|
+
import { createWriteStream } from 'node:fs';
|
|
56
|
+
import { styleText } from 'node:util';
|
|
57
|
+
import { capitalize } from 'utilium';
|
|
58
|
+
import * as z from 'zod';
|
|
59
|
+
import { cliOptions as opts, rlConfirm } from '../cli.js';
|
|
60
|
+
import * as db from './index.js';
|
|
61
|
+
const axiumDB = program.command('db').alias('database').description('Manage the database').addOption(opts.timeout);
|
|
62
|
+
export async function dbInitTables() {
|
|
63
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
64
|
+
try {
|
|
65
|
+
const info = db.getUpgradeInfo();
|
|
66
|
+
const schema = db.schema.getFull({ exclude: Object.keys(info.current) });
|
|
67
|
+
const delta = db.delta.compute({ tables: {}, indexes: {} }, schema);
|
|
68
|
+
if (db.delta.isEmpty(delta))
|
|
69
|
+
return;
|
|
70
|
+
for (const text of db.delta.display(delta))
|
|
71
|
+
console.log(text);
|
|
72
|
+
await rlConfirm();
|
|
73
|
+
const _ = __addDisposableResource(env_1, db.connect(), true);
|
|
74
|
+
await db.delta.apply(delta);
|
|
75
|
+
Object.assign(info.current, schema.versions);
|
|
76
|
+
db.setUpgradeInfo(info);
|
|
77
|
+
}
|
|
78
|
+
catch (e_1) {
|
|
79
|
+
env_1.error = e_1;
|
|
80
|
+
env_1.hasError = true;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
const result_1 = __disposeResources(env_1);
|
|
84
|
+
if (result_1)
|
|
85
|
+
await result_1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
axiumDB
|
|
89
|
+
.command('init')
|
|
90
|
+
.description('Initialize the database')
|
|
91
|
+
.addOption(opts.force)
|
|
92
|
+
.option('-s, --skip', 'If the user, database, or schema already exists, skip trying to create it.', false)
|
|
93
|
+
.addOption(opts.check)
|
|
94
|
+
.action(async function axium_db_init() {
|
|
95
|
+
const opt = this.optsWithGlobals();
|
|
96
|
+
await db.init(opt);
|
|
97
|
+
await dbInitTables();
|
|
98
|
+
});
|
|
99
|
+
axiumDB
|
|
100
|
+
.command('status')
|
|
101
|
+
.alias('stats')
|
|
102
|
+
.description('Check the status of the database')
|
|
103
|
+
.action(async () => {
|
|
104
|
+
try {
|
|
105
|
+
console.log(await db.statText());
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
io.error('Unavailable');
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
axiumDB
|
|
113
|
+
.command('drop')
|
|
114
|
+
.description('Drop the Axium database and user')
|
|
115
|
+
.addOption(opts.force)
|
|
116
|
+
.action(async (opt) => {
|
|
117
|
+
const stats = await db.count('users', 'passkeys', 'sessions');
|
|
118
|
+
if (!opt.force)
|
|
119
|
+
for (const key of ['users', 'passkeys', 'sessions']) {
|
|
120
|
+
if (stats[key] == 0)
|
|
121
|
+
continue;
|
|
122
|
+
io.warn(`Database has existing ${key}. Use --force if you really want to drop the database.`);
|
|
123
|
+
process.exit(2);
|
|
124
|
+
}
|
|
125
|
+
await db._sql('DROP DATABASE axium', 'Dropping database');
|
|
126
|
+
await db._sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
|
|
127
|
+
await db._sql('DROP USER axium', 'Dropping user');
|
|
128
|
+
await db
|
|
129
|
+
.getHBA(opt)
|
|
130
|
+
.then(([content, writeBack]) => {
|
|
131
|
+
io.start('Checking for Axium HBA configuration');
|
|
132
|
+
if (!content.includes(db._pgHba))
|
|
133
|
+
throw 'missing.';
|
|
134
|
+
io.done();
|
|
135
|
+
io.start('Removing Axium HBA configuration');
|
|
136
|
+
const newContent = content.replace(db._pgHba, '');
|
|
137
|
+
io.done();
|
|
138
|
+
writeBack(newContent);
|
|
139
|
+
})
|
|
140
|
+
.catch(io.warn);
|
|
141
|
+
});
|
|
142
|
+
axiumDB
|
|
143
|
+
.command('wipe')
|
|
144
|
+
.description('Wipe the database')
|
|
145
|
+
.addOption(opts.force)
|
|
146
|
+
.action(async (opt) => {
|
|
147
|
+
const tables = new Map();
|
|
148
|
+
for (const [plugin, schema] of db.schema.getFiles()) {
|
|
149
|
+
for (const table of schema.wipe) {
|
|
150
|
+
const maybePlugin = tables.get(table);
|
|
151
|
+
tables.set(table, maybePlugin ? `${maybePlugin}, ${plugin}` : plugin);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!opt.force) {
|
|
155
|
+
const stats = await db.count(...tables.keys());
|
|
156
|
+
const nonEmpty = Object.entries(stats)
|
|
157
|
+
.filter(([, v]) => v)
|
|
158
|
+
.map(([k]) => k);
|
|
159
|
+
if (nonEmpty.length) {
|
|
160
|
+
io.exit(`Some tables are not empty, use --force if you really want to wipe them: ${nonEmpty.join(', ')}`, 2);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const maxTableName = Math.max(5, ...Array.from(tables.keys()).map(t => t.length));
|
|
164
|
+
console.log('Table' + ' '.repeat(maxTableName - 5), '|', 'Plugin(s)');
|
|
165
|
+
console.log('-'.repeat(maxTableName), '|', '-'.repeat(20));
|
|
166
|
+
for (const [table, plugins] of [...tables].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
167
|
+
console.log(table + ' '.repeat(maxTableName - table.length), '|', plugins);
|
|
168
|
+
}
|
|
169
|
+
await rlConfirm('Are you sure you want to wipe these tables and any dependents');
|
|
170
|
+
await db.database.deleteFrom(Array.from(tables.keys())).execute();
|
|
171
|
+
});
|
|
172
|
+
axiumDB
|
|
173
|
+
.command('check')
|
|
174
|
+
.description('Check the structure of the database')
|
|
175
|
+
.option('-s, --strict', 'Throw errors instead of emitting warnings for most column problems')
|
|
176
|
+
.action(async (opt) => {
|
|
177
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
178
|
+
try {
|
|
179
|
+
await io.run('Checking for sudo', 'which sudo');
|
|
180
|
+
await io.run('Checking for psql', 'which psql');
|
|
181
|
+
const throwUnlessRows = (text) => {
|
|
182
|
+
if (text.includes('(0 rows)'))
|
|
183
|
+
throw 'missing.';
|
|
184
|
+
return text;
|
|
185
|
+
};
|
|
186
|
+
await db._sql(`SELECT 1 FROM pg_database WHERE datname = 'axium'`, 'Checking for database').then(throwUnlessRows);
|
|
187
|
+
await db._sql(`SELECT 1 FROM pg_roles WHERE rolname = 'axium'`, 'Checking for user').then(throwUnlessRows);
|
|
188
|
+
io.start('Connecting to database');
|
|
189
|
+
const _ = __addDisposableResource(env_2, db.connect(), true);
|
|
190
|
+
io.done();
|
|
191
|
+
io.start('Getting schema metadata');
|
|
192
|
+
const schemas = await db.database.introspection.getSchemas();
|
|
193
|
+
io.done();
|
|
194
|
+
io.start('Checking for acl schema');
|
|
195
|
+
if (!schemas.find(s => s.name == 'acl'))
|
|
196
|
+
io.exit('missing.');
|
|
197
|
+
io.done();
|
|
198
|
+
io.start('Getting table metadata');
|
|
199
|
+
const tablePromises = await Promise.all([
|
|
200
|
+
db.database.introspection.getTables(),
|
|
201
|
+
db.database.withSchema('acl').introspection.getTables(),
|
|
202
|
+
]);
|
|
203
|
+
const tableMetadata = tablePromises.flat();
|
|
204
|
+
const tables = Object.fromEntries(tableMetadata.map(t => [t.schema == 'public' ? t.name : `${t.schema}.${t.name}`, t]));
|
|
205
|
+
io.done();
|
|
206
|
+
io.start('Resolving database schemas');
|
|
207
|
+
let schema;
|
|
208
|
+
try {
|
|
209
|
+
schema = db.schema.getFull();
|
|
210
|
+
io.done();
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
io.exit(e);
|
|
214
|
+
}
|
|
215
|
+
for (const [name, table] of Object.entries(schema.tables)) {
|
|
216
|
+
await db.checkTableTypes(name, table, opt, tableMetadata);
|
|
217
|
+
delete tables[name];
|
|
218
|
+
}
|
|
219
|
+
io.start('Checking for extra tables');
|
|
220
|
+
const unchecked = Object.keys(tables).join(', ');
|
|
221
|
+
if (!unchecked.length)
|
|
222
|
+
io.done();
|
|
223
|
+
else if (opt.strict)
|
|
224
|
+
io.exit(unchecked);
|
|
225
|
+
else
|
|
226
|
+
io.warn(unchecked);
|
|
227
|
+
}
|
|
228
|
+
catch (e_2) {
|
|
229
|
+
env_2.error = e_2;
|
|
230
|
+
env_2.hasError = true;
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
const result_2 = __disposeResources(env_2);
|
|
234
|
+
if (result_2)
|
|
235
|
+
await result_2;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
axiumDB
|
|
239
|
+
.command('clean')
|
|
240
|
+
.description('Remove expired rows')
|
|
241
|
+
.addOption(opts.force)
|
|
242
|
+
.action(async (opt) => {
|
|
243
|
+
await db.clean(opt);
|
|
244
|
+
});
|
|
245
|
+
axiumDB
|
|
246
|
+
.command('rotate-password')
|
|
247
|
+
.description('Generate a new password for the database user and update the config')
|
|
248
|
+
.action(db.rotatePassword);
|
|
249
|
+
axiumDB
|
|
250
|
+
.command('json-schema')
|
|
251
|
+
.description('Get the JSON schema for the database configuration file')
|
|
252
|
+
.option('-j, --json', 'values are JSON encoded')
|
|
253
|
+
.action(opt => {
|
|
254
|
+
try {
|
|
255
|
+
const schema = z.toJSONSchema(db.schema.SchemaFile, { io: 'input' });
|
|
256
|
+
console.log(opt.json ? JSON.stringify(schema, null, 4) : schema);
|
|
257
|
+
}
|
|
258
|
+
catch (e) {
|
|
259
|
+
io.exit(e);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
axiumDB
|
|
263
|
+
.command('upgrade')
|
|
264
|
+
.alias('update')
|
|
265
|
+
.alias('up')
|
|
266
|
+
.description('Upgrade the database to the latest version')
|
|
267
|
+
.option('--abort', 'Rollback changes instead of committing them')
|
|
268
|
+
.action(async function axium_db_upgrade(opt) {
|
|
269
|
+
const deltas = [];
|
|
270
|
+
const info = db.getUpgradeInfo();
|
|
271
|
+
let empty = true;
|
|
272
|
+
const from = {}, to = {};
|
|
273
|
+
for (const [name, schema] of db.schema.getFiles()) {
|
|
274
|
+
if (!(name in info.current))
|
|
275
|
+
io.exit('Plugin is not initialized: ' + name);
|
|
276
|
+
const currentVersion = info.current[name];
|
|
277
|
+
const target = schema.latest ?? schema.versions.length - 1;
|
|
278
|
+
if (currentVersion >= target)
|
|
279
|
+
continue;
|
|
280
|
+
from[name] = currentVersion;
|
|
281
|
+
to[name] = target;
|
|
282
|
+
info.current[name] = target;
|
|
283
|
+
let versions = schema.versions.slice(currentVersion + 1);
|
|
284
|
+
const v0 = schema.versions[0];
|
|
285
|
+
if (v0.delta)
|
|
286
|
+
throw 'Initial version can not be a delta';
|
|
287
|
+
for (const [i, v] of versions.toReversed().entries()) {
|
|
288
|
+
if (v.delta || v == v0)
|
|
289
|
+
continue;
|
|
290
|
+
versions = [db.delta.compute(v0, v), ...versions.slice(-i)];
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
const delta = db.delta.collapse(versions);
|
|
294
|
+
deltas.push(delta);
|
|
295
|
+
console.log('Upgrading', name, styleText('dim', currentVersion.toString() + '->') + styleText('blueBright', target.toString()) + ':');
|
|
296
|
+
if (!db.delta.isEmpty(delta))
|
|
297
|
+
empty = false;
|
|
298
|
+
for (const text of db.delta.display(delta))
|
|
299
|
+
console.log(text);
|
|
300
|
+
}
|
|
301
|
+
if (empty) {
|
|
302
|
+
console.log('Already up to date.');
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (opt.abort) {
|
|
306
|
+
io.warn('--abort: Changes will be rolled back instead of being committed.');
|
|
307
|
+
}
|
|
308
|
+
await rlConfirm();
|
|
309
|
+
io.start('Computing delta');
|
|
310
|
+
let delta;
|
|
311
|
+
try {
|
|
312
|
+
delta = db.delta.collapse(deltas);
|
|
313
|
+
io.done();
|
|
314
|
+
}
|
|
315
|
+
catch (e) {
|
|
316
|
+
io.exit(e);
|
|
317
|
+
}
|
|
318
|
+
io.start('Validating delta');
|
|
319
|
+
try {
|
|
320
|
+
db.delta.validate(delta);
|
|
321
|
+
io.done();
|
|
322
|
+
}
|
|
323
|
+
catch (e) {
|
|
324
|
+
io.exit(e);
|
|
325
|
+
}
|
|
326
|
+
console.log('Applying delta.');
|
|
327
|
+
await db.delta.apply(delta, opt.abort);
|
|
328
|
+
info.upgrades.push({ timestamp: new Date(), from, to });
|
|
329
|
+
db.setUpgradeInfo(info);
|
|
330
|
+
});
|
|
331
|
+
axiumDB
|
|
332
|
+
.command('upgrade-history')
|
|
333
|
+
.alias('update-history')
|
|
334
|
+
.description('Show the history of database upgrades')
|
|
335
|
+
.action(() => {
|
|
336
|
+
const info = db.getUpgradeInfo();
|
|
337
|
+
if (!info.upgrades.length) {
|
|
338
|
+
console.log('No upgrade history.');
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
for (const up of info.upgrades) {
|
|
342
|
+
console.log(styleText(['whiteBright', 'underline'], up.timestamp.toString()) + ':');
|
|
343
|
+
for (const [name, from] of Object.entries(up.from)) {
|
|
344
|
+
console.log(name, styleText('dim', from.toString() + '->') + styleText('blueBright', up.to[name].toString()));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
function colorCurrent(info) {
|
|
349
|
+
if (info.current > Math.max(info.latest, info.available))
|
|
350
|
+
return 'magentaBright';
|
|
351
|
+
if (info.current > info.latest && info.current <= info.available)
|
|
352
|
+
return 'cyanBright';
|
|
353
|
+
if (info.current >= info.latest)
|
|
354
|
+
return 'greenBright';
|
|
355
|
+
return 'yellowBright';
|
|
356
|
+
}
|
|
357
|
+
axiumDB
|
|
358
|
+
.command('versions')
|
|
359
|
+
.description('Show information about database versions')
|
|
360
|
+
.action(() => {
|
|
361
|
+
const { current: currentVersions } = db.getUpgradeInfo();
|
|
362
|
+
const lengths = { name: 4, current: 7, latest: 6, available: 9 };
|
|
363
|
+
const entries = [];
|
|
364
|
+
for (const [name, file] of db.schema.getFiles()) {
|
|
365
|
+
const available = file.versions.length - 1;
|
|
366
|
+
const latest = file.latest ?? available;
|
|
367
|
+
const current = currentVersions[name];
|
|
368
|
+
entries.push({ name, latest, available, current });
|
|
369
|
+
lengths.name = Math.max(lengths.name || 0, name.length);
|
|
370
|
+
lengths.current = Math.max(lengths.current || 0, current.toString().length);
|
|
371
|
+
lengths.latest = Math.max(lengths.latest || 0, latest.toString().length);
|
|
372
|
+
lengths.available = Math.max(lengths.available || 0, available.toString().length);
|
|
373
|
+
}
|
|
374
|
+
console.log(...['name', 'current', 'latest', 'available'].map(key => styleText(['whiteBright', 'underline'], capitalize(key).padStart(lengths[key]))));
|
|
375
|
+
for (const entry of entries) {
|
|
376
|
+
console.log(entry.name.padStart(lengths.name), styleText(colorCurrent(entry), entry.current.toString().padStart(lengths.current)), entry.latest.toString().padStart(lengths.latest), entry.available.toString().padStart(lengths.available));
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
axiumDB
|
|
380
|
+
.command('export-schema')
|
|
381
|
+
.description('Export the DB schema')
|
|
382
|
+
.addOption(new Option('-f, --format <format>', 'Output format').choices(['sql', 'graph']).default('sql'))
|
|
383
|
+
.option('-o, --output <file>', 'Output file path')
|
|
384
|
+
.action(opt => {
|
|
385
|
+
const schema = db.schema.getFull();
|
|
386
|
+
const it = opt.format == 'sql' ? db.schema.toSQL(schema) : db.schema.toGraph(schema);
|
|
387
|
+
const out = opt.output ? createWriteStream(opt.output) : process.stdout;
|
|
388
|
+
for (const data of it)
|
|
389
|
+
out.write(data);
|
|
390
|
+
if (opt.output)
|
|
391
|
+
out.close();
|
|
392
|
+
});
|
package/dist/db/connection.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Kysely } from 'kysely';
|
|
2
|
-
import type { Schema } from '../
|
|
2
|
+
import type { Schema } from '../db/index.js';
|
|
3
3
|
export type Database = Kysely<Schema> & AsyncDisposable;
|
|
4
4
|
export declare let database: Database;
|
|
5
5
|
export declare function connect(): Database;
|
|
@@ -3,11 +3,10 @@ import type { AuthenticatorTransportFuture, CredentialDeviceType } from '@simple
|
|
|
3
3
|
import type * as kysely from 'kysely';
|
|
4
4
|
import type { Expand } from 'utilium';
|
|
5
5
|
import * as z from 'zod';
|
|
6
|
-
import { connect, database } from './
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
export * as schema from './db/schema.js';
|
|
6
|
+
import { connect, database } from './connection.js';
|
|
7
|
+
import * as schema from './schema.js';
|
|
8
|
+
export * as delta from './delta.js';
|
|
9
|
+
export { connect, database, schema };
|
|
11
10
|
export interface DBAccessControl {
|
|
12
11
|
itemId: string;
|
|
13
12
|
userId?: string | null;
|
|
@@ -60,13 +60,12 @@ import { join } from 'node:path';
|
|
|
60
60
|
import { styleText } from 'node:util';
|
|
61
61
|
import pg from 'pg';
|
|
62
62
|
import * as z from 'zod';
|
|
63
|
-
import config from '
|
|
64
|
-
import { dirs, systemDir } from '
|
|
65
|
-
import { connect, database } from './
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
export
|
|
69
|
-
export * as schema from './db/schema.js';
|
|
63
|
+
import config from '../config.js';
|
|
64
|
+
import { dirs, systemDir } from '../io.js';
|
|
65
|
+
import { connect, database } from './connection.js';
|
|
66
|
+
import * as schema from './schema.js';
|
|
67
|
+
export * as delta from './delta.js';
|
|
68
|
+
export { connect, database, schema };
|
|
70
69
|
pg.types.setTypeParser(pg.types.builtins.INT8, BigInt);
|
|
71
70
|
// @ts-expect-error 2339
|
|
72
71
|
BigInt.prototype.toJSON = function () {
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/linking.d.ts
CHANGED
package/dist/linking.js
CHANGED
|
@@ -3,27 +3,22 @@ import { plugins } from '@axium/core/plugins';
|
|
|
3
3
|
import { existsSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { join, relative, resolve } from 'node:path/posix';
|
|
5
5
|
import config from './config.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
function info(id) {
|
|
10
|
-
const text = id.startsWith('#') ? textFor[id.slice(1)] : `routes for plugin: ${id}`;
|
|
11
|
-
const link = join(config.web.routes, `(${id.startsWith('#') ? id.slice(1) : id.replaceAll('/', '__')})`);
|
|
12
|
-
return [text, link];
|
|
6
|
+
function resolveLink(id) {
|
|
7
|
+
return join(config.web.routes, `(${id.startsWith('#') ? id.slice(1) : id.replaceAll('/', '__')})`);
|
|
13
8
|
}
|
|
14
9
|
export function* listRouteLinks(options = {}) {
|
|
15
10
|
if (!options.only || !options.only.length) {
|
|
16
|
-
const
|
|
17
|
-
yield {
|
|
11
|
+
const link = resolveLink('#builtin');
|
|
12
|
+
yield { id: '#builtin', from: link, to: resolve(import.meta.dirname, '../routes') };
|
|
18
13
|
}
|
|
19
14
|
for (const plugin of plugins.values()) {
|
|
20
15
|
if (!plugin.server?.routes)
|
|
21
16
|
continue;
|
|
22
17
|
if (options.only && options.only.length && !options.only.includes(plugin.name))
|
|
23
18
|
continue;
|
|
24
|
-
const
|
|
19
|
+
const link = resolveLink(plugin.name);
|
|
25
20
|
const to = resolve(join(plugin.dirname, plugin.server.routes));
|
|
26
|
-
yield {
|
|
21
|
+
yield { id: plugin.name, from: link, to };
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
24
|
/**
|
|
@@ -31,27 +26,12 @@ export function* listRouteLinks(options = {}) {
|
|
|
31
26
|
*/
|
|
32
27
|
export function linkRoutes(options = {}) {
|
|
33
28
|
for (const info of listRouteLinks(options)) {
|
|
34
|
-
const {
|
|
35
|
-
io.start('Linking ' + text);
|
|
29
|
+
const { from, to } = info;
|
|
36
30
|
if (existsSync(from)) {
|
|
37
|
-
|
|
38
|
-
io.start('Unlinking ' + text);
|
|
39
|
-
try {
|
|
40
|
-
unlinkSync(from);
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
io.exit(e);
|
|
44
|
-
}
|
|
45
|
-
io.done();
|
|
46
|
-
io.start('Re-linking ' + text);
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
symlinkSync(to, from, 'dir');
|
|
50
|
-
io.done();
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
io.exit(e);
|
|
31
|
+
unlinkSync(from);
|
|
54
32
|
}
|
|
33
|
+
io.debug('Linking routes:', from, '->', to);
|
|
34
|
+
symlinkSync(to, from, 'dir');
|
|
55
35
|
}
|
|
56
36
|
}
|
|
57
37
|
const hooksBuiltin = `
|
|
@@ -64,7 +44,6 @@ export function handleError({ error, status }) {
|
|
|
64
44
|
`;
|
|
65
45
|
export function writePluginHooks() {
|
|
66
46
|
const hooksPath = join(import.meta.dirname, '../.hooks.js');
|
|
67
|
-
io.start('Writing web client hooks for plugins');
|
|
68
47
|
let hooks = `// auto-generated plugin hooks //\n`;
|
|
69
48
|
for (const plugin of plugins.values()) {
|
|
70
49
|
if (!plugin.server?.web_client_hooks)
|
|
@@ -74,21 +53,14 @@ export function writePluginHooks() {
|
|
|
74
53
|
}
|
|
75
54
|
hooks += hooksBuiltin;
|
|
76
55
|
writeFileSync(hooksPath, hooks, 'utf8');
|
|
77
|
-
io.
|
|
78
|
-
io.debug('Wrote', hooksPath);
|
|
56
|
+
io.debug('Wrote hooks to', hooksPath);
|
|
79
57
|
}
|
|
80
58
|
export function unlinkRoutes(options = {}) {
|
|
81
59
|
for (const info of listRouteLinks(options)) {
|
|
82
|
-
const {
|
|
60
|
+
const { from } = info;
|
|
83
61
|
if (!existsSync(from))
|
|
84
62
|
return;
|
|
85
|
-
io.
|
|
86
|
-
|
|
87
|
-
unlinkSync(from);
|
|
88
|
-
io.done();
|
|
89
|
-
}
|
|
90
|
-
catch (e) {
|
|
91
|
-
io.exit(e);
|
|
92
|
-
}
|
|
63
|
+
io.debug('Unlinking routes:', from);
|
|
64
|
+
unlinkSync(from);
|
|
93
65
|
}
|
|
94
66
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import './db/cli.js';
|