@axium/server 0.9.0 → 0.11.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.
Files changed (77) hide show
  1. package/assets/icons/brands.svg +1493 -0
  2. package/{web/api/index.ts → dist/api/index.d.ts} +0 -2
  3. package/dist/api/index.js +5 -0
  4. package/dist/api/metadata.d.ts +1 -0
  5. package/dist/api/metadata.js +28 -0
  6. package/dist/api/passkeys.d.ts +1 -0
  7. package/dist/api/passkeys.js +50 -0
  8. package/dist/api/register.d.ts +1 -0
  9. package/dist/api/register.js +70 -0
  10. package/dist/api/session.d.ts +1 -0
  11. package/dist/api/session.js +31 -0
  12. package/dist/api/users.d.ts +1 -0
  13. package/dist/api/users.js +244 -0
  14. package/dist/apps.d.ts +0 -5
  15. package/dist/apps.js +2 -9
  16. package/dist/auth.d.ts +14 -30
  17. package/dist/auth.js +12 -18
  18. package/dist/cli.js +289 -32
  19. package/dist/config.d.ts +21 -8
  20. package/dist/config.js +46 -17
  21. package/dist/database.d.ts +12 -12
  22. package/dist/database.js +83 -84
  23. package/dist/io.d.ts +19 -20
  24. package/dist/io.js +85 -56
  25. package/dist/linking.d.ts +10 -0
  26. package/dist/linking.js +76 -0
  27. package/dist/plugins.d.ts +28 -12
  28. package/dist/plugins.js +29 -25
  29. package/dist/requests.d.ts +14 -0
  30. package/dist/requests.js +67 -0
  31. package/dist/routes.d.ts +12 -13
  32. package/dist/routes.js +21 -22
  33. package/dist/serve.d.ts +7 -0
  34. package/dist/serve.js +11 -0
  35. package/dist/state.d.ts +4 -0
  36. package/dist/state.js +22 -0
  37. package/dist/sveltekit.d.ts +8 -0
  38. package/dist/sveltekit.js +94 -0
  39. package/package.json +17 -8
  40. package/{web/routes → routes}/account/+page.svelte +6 -5
  41. package/svelte.config.js +37 -0
  42. package/web/hooks.server.ts +8 -3
  43. package/web/lib/Dialog.svelte +0 -1
  44. package/web/lib/FormDialog.svelte +0 -1
  45. package/web/lib/Upload.svelte +58 -0
  46. package/web/lib/icons/Icon.svelte +2 -7
  47. package/web/lib/icons/index.ts +6 -3
  48. package/web/lib/icons/mime.json +2 -1
  49. package/web/template.html +18 -0
  50. package/web/tsconfig.json +2 -2
  51. package/web/api/metadata.ts +0 -35
  52. package/web/api/passkeys.ts +0 -56
  53. package/web/api/readme.md +0 -1
  54. package/web/api/register.ts +0 -83
  55. package/web/api/schemas.ts +0 -22
  56. package/web/api/session.ts +0 -33
  57. package/web/api/users.ts +0 -351
  58. package/web/api/utils.ts +0 -66
  59. package/web/app.html +0 -14
  60. package/web/auth.ts +0 -8
  61. package/web/index.server.ts +0 -1
  62. package/web/index.ts +0 -1
  63. package/web/lib/auth.ts +0 -12
  64. package/web/lib/index.ts +0 -5
  65. package/web/routes/+layout.svelte +0 -6
  66. package/web/routes/[...path]/+page.server.ts +0 -13
  67. package/web/routes/[appId]/[...page]/+page.server.ts +0 -14
  68. package/web/routes/api/[...path]/+server.ts +0 -49
  69. package/web/utils.ts +0 -26
  70. /package/{web/lib → assets}/icons/light.svg +0 -0
  71. /package/{web/lib → assets}/icons/regular.svg +0 -0
  72. /package/{web/lib → assets}/icons/solid.svg +0 -0
  73. /package/{web/lib → assets}/styles.css +0 -0
  74. /package/{web/routes → routes}/_axium/default/+page.svelte +0 -0
  75. /package/{web/routes → routes}/login/+page.svelte +0 -0
  76. /package/{web/routes → routes}/logout/+page.svelte +0 -0
  77. /package/{web/routes → routes}/register/+page.svelte +0 -0
@@ -1,16 +1,19 @@
1
1
  import type { Preferences } from '@axium/core';
2
+ import type { AuthenticatorTransportFuture, CredentialDeviceType } from '@simplewebauthn/server';
2
3
  import { Kysely, type GeneratedAlways } from 'kysely';
3
4
  import type { VerificationRole } from './auth.js';
4
- import type { MaybeOutput, WithOutput } from './io.js';
5
- import type { AuthenticatorTransportFuture, CredentialDeviceType } from '@simplewebauthn/server';
6
5
  export interface Schema {
7
6
  users: {
8
- id: GeneratedAlways<string> & string;
7
+ id: string;
9
8
  email: string;
10
9
  name: string;
11
10
  image?: string | null;
12
11
  emailVerified?: Date | null;
13
- preferences?: Preferences;
12
+ preferences: Preferences;
13
+ isAdmin: boolean;
14
+ roles: string[];
15
+ tags: string[];
16
+ registeredAt: GeneratedAlways<Date>;
14
17
  };
15
18
  sessions: {
16
19
  id: GeneratedAlways<string>;
@@ -49,19 +52,16 @@ export interface Stats {
49
52
  export declare function count<const T extends keyof Schema>(table: T): Promise<number>;
50
53
  export declare function status(): Promise<Stats>;
51
54
  export declare function statusText(): Promise<string>;
52
- export interface OpOptions extends MaybeOutput {
53
- timeout: number;
55
+ export interface OpOptions {
54
56
  force: boolean;
55
57
  }
56
58
  export interface InitOptions extends OpOptions {
57
59
  skip: boolean;
58
60
  }
59
- export declare function shouldRecreate(opt: InitOptions & WithOutput): boolean;
60
- export declare function getHBA(opt: OpOptions & WithOutput): Promise<[content: string, writeBack: (newContent: string) => void]>;
61
- export interface PluginShortcuts {
62
- done: () => void;
63
- warnExists: (error: string | Error) => void;
64
- }
61
+ export declare function shouldRecreate(opt: InitOptions): boolean;
62
+ export declare function getHBA(opt: OpOptions): Promise<[content: string, writeBack: (newContent: string) => void]>;
63
+ /** Shortcut to output a warning if an error is thrown because relation already exists */
64
+ export declare const warnExists: (error: string | Error) => void;
65
65
  export declare function init(opt: InitOptions): Promise<void>;
66
66
  export declare function check(opt: OpOptions): Promise<void>;
67
67
  export declare function clean(opt: Partial<OpOptions>): Promise<void>;
package/dist/database.js CHANGED
@@ -55,12 +55,15 @@ import { randomBytes } from 'node:crypto';
55
55
  import { readFileSync, writeFileSync } from 'node:fs';
56
56
  import pg from 'pg';
57
57
  import config from './config.js';
58
- import { _fixOutput, run, someWarnings } from './io.js';
58
+ import * as io from './io.js';
59
59
  import { plugins } from './plugins.js';
60
+ const sym = Symbol.for('Axium:database');
60
61
  export let database;
61
62
  export function connect() {
62
63
  if (database)
63
64
  return database;
65
+ if (globalThis[sym])
66
+ return (database = globalThis[sym]);
64
67
  const _db = new Kysely({
65
68
  dialect: new PostgresDialect({ pool: new pg.Pool(config.db) }),
66
69
  });
@@ -69,6 +72,7 @@ export function connect() {
69
72
  await _db.destroy();
70
73
  },
71
74
  });
75
+ globalThis[sym] = database;
72
76
  return database;
73
77
  }
74
78
  export async function count(table) {
@@ -95,32 +99,32 @@ export async function statusText() {
95
99
  }
96
100
  export function shouldRecreate(opt) {
97
101
  if (opt.skip) {
98
- opt.output('warn', 'already exists. (skipped)');
102
+ io.warn('already exists. (skipped)');
99
103
  return true;
100
104
  }
101
105
  if (opt.force) {
102
- opt.output('warn', 'already exists. (re-creating)');
106
+ io.warn('already exists. (re-creating)');
103
107
  return false;
104
108
  }
105
- opt.output('warn', 'already exists. Use --skip to skip or --force to re-create.');
109
+ io.warn('already exists. Use --skip to skip or --force to re-create.');
106
110
  throw 2;
107
111
  }
108
112
  export async function getHBA(opt) {
109
- const hbaShowResult = await run(opt, 'Finding pg_hba.conf', `sudo -u postgres psql -c "SHOW hba_file"`);
110
- opt.output('start', 'Resolving pg_hba.conf path');
113
+ const hbaShowResult = await io.run('Finding pg_hba.conf', `sudo -u postgres psql -c "SHOW hba_file"`);
114
+ io.start('Resolving pg_hba.conf path');
111
115
  const hbaPath = hbaShowResult.match(/^\s*(.+\.conf)\s*$/m)?.[1]?.trim();
112
116
  if (!hbaPath) {
113
117
  throw 'failed. You will need to add password-based auth for the axium user manually.';
114
118
  }
115
- opt.output('done');
116
- opt.output('debug', `Found pg_hba.conf at ${hbaPath}`);
117
- opt.output('start', 'Reading HBA configuration');
119
+ io.done();
120
+ io.debug(`Found pg_hba.conf at ${hbaPath}`);
121
+ io.start('Reading HBA configuration');
118
122
  const content = readFileSync(hbaPath, 'utf-8');
119
- opt.output('done');
123
+ io.done();
120
124
  const writeBack = (newContent) => {
121
- opt.output('start', 'Writing HBA configuration');
125
+ io.start('Writing HBA configuration');
122
126
  writeFileSync(hbaPath, newContent);
123
- opt.output('done');
127
+ io.done();
124
128
  };
125
129
  return [content, writeBack];
126
130
  }
@@ -129,19 +133,23 @@ local axium axium md5
129
133
  host axium axium 127.0.0.1/32 md5
130
134
  host axium axium ::1/128 md5
131
135
  `;
136
+ const _sql = (command, message) => io.run(message, `sudo -u postgres psql -c "${command}"`);
137
+ /** Shortcut to output a warning if an error is thrown because relation already exists */
138
+ export const warnExists = io.someWarnings([/\w+ "[\w.]+" already exists/, 'already exists.']);
139
+ const throwUnlessRows = (text) => {
140
+ if (text.includes('(0 rows)'))
141
+ throw 'missing.';
142
+ return text;
143
+ };
132
144
  export async function init(opt) {
133
145
  const env_1 = { stack: [], error: void 0, hasError: false };
134
146
  try {
135
- _fixOutput(opt);
136
147
  if (!config.db.password) {
137
148
  config.save({ db: { password: randomBytes(32).toString('base64') } }, true);
138
- opt.output('debug', 'Generated password and wrote to global config');
149
+ io.debug('Generated password and wrote to global config');
139
150
  }
140
- await run(opt, 'Checking for sudo', 'which sudo');
141
- await run(opt, 'Checking for psql', 'which psql');
142
- const _sql = (command, message) => run(opt, message, `sudo -u postgres psql -c "${command}"`);
143
- const warnExists = someWarnings(opt.output, [/(schema|relation) "[\w.]+" already exists/, 'already exists.']);
144
- const done = () => opt.output('done');
151
+ await io.run('Checking for sudo', 'which sudo');
152
+ await io.run('Checking for psql', 'which psql');
145
153
  await _sql('CREATE DATABASE axium', 'Creating database').catch(async (error) => {
146
154
  if (error != 'database "axium" already exists')
147
155
  throw error;
@@ -165,19 +173,19 @@ export async function init(opt) {
165
173
  await _sql('ALTER DATABASE axium OWNER TO axium', 'Setting database owner');
166
174
  await getHBA(opt)
167
175
  .then(([content, writeBack]) => {
168
- opt.output('start', 'Checking for Axium HBA configuration');
176
+ io.start('Checking for Axium HBA configuration');
169
177
  if (content.includes(pgHba))
170
178
  throw 'already exists.';
171
- done();
172
- opt.output('start', 'Adding Axium HBA configuration');
179
+ io.done();
180
+ io.start('Adding Axium HBA configuration');
173
181
  const newContent = content.replace(/^local\s+all\s+all.*$/m, `$&\n${pgHba}`);
174
- done();
182
+ io.done();
175
183
  writeBack(newContent);
176
184
  })
177
- .catch(e => opt.output('warn', e));
185
+ .catch(io.warn);
178
186
  await _sql('SELECT pg_reload_conf()', 'Reloading configuration');
179
187
  const db = __addDisposableResource(env_1, connect(), true);
180
- opt.output('start', 'Creating table users');
188
+ io.start('Creating table users');
181
189
  await db.schema
182
190
  .createTable('users')
183
191
  .addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
@@ -185,11 +193,15 @@ export async function init(opt) {
185
193
  .addColumn('email', 'text', col => col.unique().notNull())
186
194
  .addColumn('emailVerified', 'timestamptz')
187
195
  .addColumn('image', 'text')
196
+ .addColumn('isAdmin', 'boolean', col => col.notNull().defaultTo(false))
197
+ .addColumn('roles', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
198
+ .addColumn('tags', sql `text[]`, col => col.notNull().defaultTo(sql `'{}'::text[]`))
188
199
  .addColumn('preferences', 'jsonb', col => col.notNull().defaultTo(sql `'{}'::jsonb`))
200
+ .addColumn('registeredAt', 'timestamptz', col => col.notNull().defaultTo(sql `now()`))
189
201
  .execute()
190
- .then(done)
202
+ .then(io.done)
191
203
  .catch(warnExists);
192
- opt.output('start', 'Creating table sessions');
204
+ io.start('Creating table sessions');
193
205
  await db.schema
194
206
  .createTable('sessions')
195
207
  .addColumn('id', 'uuid', col => col.primaryKey().defaultTo(sql `gen_random_uuid()`))
@@ -199,11 +211,11 @@ export async function init(opt) {
199
211
  .addColumn('expires', 'timestamptz', col => col.notNull())
200
212
  .addColumn('elevated', 'boolean', col => col.notNull())
201
213
  .execute()
202
- .then(done)
214
+ .then(io.done)
203
215
  .catch(warnExists);
204
- opt.output('start', 'Creating index for sessions.userId');
205
- await db.schema.createIndex('sessions_userId_index').on('sessions').column('userId').execute().then(done).catch(warnExists);
206
- opt.output('start', 'Creating table verifications');
216
+ io.start('Creating index for sessions.userId');
217
+ await db.schema.createIndex('sessions_userId_index').on('sessions').column('userId').execute().then(io.done).catch(warnExists);
218
+ io.start('Creating table verifications');
207
219
  await db.schema
208
220
  .createTable('verifications')
209
221
  .addColumn('userId', 'uuid', col => col.references('users.id').onDelete('cascade').notNull())
@@ -211,9 +223,9 @@ export async function init(opt) {
211
223
  .addColumn('expires', 'timestamptz', col => col.notNull())
212
224
  .addColumn('role', 'text', col => col.notNull())
213
225
  .execute()
214
- .then(done)
226
+ .then(io.done)
215
227
  .catch(warnExists);
216
- opt.output('start', 'Creating table passkeys');
228
+ io.start('Creating table passkeys');
217
229
  await db.schema
218
230
  .createTable('passkeys')
219
231
  .addColumn('id', 'text', col => col.primaryKey().notNull())
@@ -226,15 +238,15 @@ export async function init(opt) {
226
238
  .addColumn('backedUp', 'boolean', col => col.notNull())
227
239
  .addColumn('transports', sql `text[]`)
228
240
  .execute()
229
- .then(done)
241
+ .then(io.done)
230
242
  .catch(warnExists);
231
- opt.output('start', 'Creating index for passkeys.id');
232
- await db.schema.createIndex('passkeys_id_key').on('passkeys').column('id').execute().then(done).catch(warnExists);
243
+ io.start('Creating index for passkeys.id');
244
+ await db.schema.createIndex('passkeys_id_key').on('passkeys').column('id').execute().then(io.done).catch(warnExists);
233
245
  for (const plugin of plugins) {
234
- if (!plugin.db_init)
246
+ if (!plugin.hooks.db_init)
235
247
  continue;
236
- opt.output('plugin', plugin.name);
237
- await plugin.db_init(opt, db, { warnExists, done });
248
+ io.plugin(plugin.name);
249
+ await plugin.hooks.db_init(opt, db);
238
250
  }
239
251
  }
240
252
  catch (e_1) {
@@ -250,33 +262,25 @@ export async function init(opt) {
250
262
  export async function check(opt) {
251
263
  const env_2 = { stack: [], error: void 0, hasError: false };
252
264
  try {
253
- _fixOutput(opt);
254
- await run(opt, 'Checking for sudo', 'which sudo');
255
- await run(opt, 'Checking for psql', 'which psql');
256
- const _sql = (command, message) => run(opt, message, `sudo -u postgres psql -c "${command}"`);
257
- const done = () => opt.output('done');
258
- const throwUnlessRows = (text) => {
259
- if (text.includes('(0 rows)'))
260
- throw 'missing.';
261
- return text;
262
- };
265
+ await io.run('Checking for sudo', 'which sudo');
266
+ await io.run('Checking for psql', 'which psql');
263
267
  await _sql(`SELECT 1 FROM pg_database WHERE datname = 'axium'`, 'Checking for database').then(throwUnlessRows);
264
268
  await _sql(`SELECT 1 FROM pg_roles WHERE rolname = 'axium'`, 'Checking for user').then(throwUnlessRows);
265
- opt.output('start', 'Connecting to database');
269
+ io.start('Connecting to database');
266
270
  const db = __addDisposableResource(env_2, connect(), true);
267
- done();
268
- opt.output('start', `Checking users table`);
269
- await db.selectFrom('users').select(['id', 'email', 'emailVerified', 'image', 'name', 'preferences']).execute().then(done);
270
- opt.output('start', `Checking sessions table`);
271
- await db.selectFrom('sessions').select(['id', 'userId', 'token', 'created', 'expires', 'elevated']).execute().then(done);
272
- opt.output('start', `Checking verifications table`);
273
- await db.selectFrom('verifications').select(['userId', 'token', 'expires', 'role']).execute().then(done);
274
- opt.output('start', `Checking passkeys table`);
271
+ io.done();
272
+ io.start('Checking users table');
273
+ await db.selectFrom('users').select(['id', 'email', 'emailVerified', 'image', 'name', 'preferences']).execute().then(io.done);
274
+ io.start('Checking sessions table');
275
+ await db.selectFrom('sessions').select(['id', 'userId', 'token', 'created', 'expires', 'elevated']).execute().then(io.done);
276
+ io.start('Checking verifications table');
277
+ await db.selectFrom('verifications').select(['userId', 'token', 'expires', 'role']).execute().then(io.done);
278
+ io.start('Checking passkeys table');
275
279
  await db
276
280
  .selectFrom('passkeys')
277
281
  .select(['id', 'name', 'createdAt', 'userId', 'publicKey', 'counter', 'deviceType', 'backedUp', 'transports'])
278
282
  .execute()
279
- .then(done);
283
+ .then(io.done);
280
284
  }
281
285
  catch (e_2) {
282
286
  env_2.error = e_2;
@@ -289,19 +293,17 @@ export async function check(opt) {
289
293
  }
290
294
  }
291
295
  export async function clean(opt) {
292
- _fixOutput(opt);
293
- const done = () => opt.output('done');
294
296
  const now = new Date();
295
297
  const db = connect();
296
- opt.output('start', 'Removing expired sessions');
297
- await db.deleteFrom('sessions').where('sessions.expires', '<', now).execute().then(done);
298
- opt.output('start', 'Removing expired verifications');
299
- await db.deleteFrom('verifications').where('verifications.expires', '<', now).execute().then(done);
298
+ io.start('Removing expired sessions');
299
+ await db.deleteFrom('sessions').where('sessions.expires', '<', now).execute().then(io.done);
300
+ io.start('Removing expired verifications');
301
+ await db.deleteFrom('verifications').where('verifications.expires', '<', now).execute().then(io.done);
300
302
  for (const plugin of plugins) {
301
- if (!plugin.db_clean)
303
+ if (!plugin.hooks.clean)
302
304
  continue;
303
- opt.output('plugin', plugin.name);
304
- await plugin.db_clean(opt, db);
305
+ io.plugin(plugin.name);
306
+ await plugin.hooks.clean(opt, db);
305
307
  }
306
308
  }
307
309
  /**
@@ -310,30 +312,28 @@ export async function clean(opt) {
310
312
  export async function uninstall(opt) {
311
313
  const env_3 = { stack: [], error: void 0, hasError: false };
312
314
  try {
313
- _fixOutput(opt);
314
315
  const db = __addDisposableResource(env_3, connect(), true);
315
316
  for (const plugin of plugins) {
316
- if (!plugin.db_remove)
317
+ if (!plugin.hooks.remove)
317
318
  continue;
318
- opt.output('plugin', plugin.name);
319
- await plugin.db_remove(opt, db);
319
+ io.plugin(plugin.name);
320
+ await plugin.hooks.remove(opt, db);
320
321
  }
321
- const _sql = (command, message) => run(opt, message, `sudo -u postgres psql -c "${command}"`);
322
322
  await _sql('DROP DATABASE axium', 'Dropping database');
323
323
  await _sql('REVOKE ALL PRIVILEGES ON SCHEMA public FROM axium', 'Revoking schema privileges');
324
324
  await _sql('DROP USER axium', 'Dropping user');
325
325
  await getHBA(opt)
326
326
  .then(([content, writeBack]) => {
327
- opt.output('start', 'Checking for Axium HBA configuration');
327
+ io.start('Checking for Axium HBA configuration');
328
328
  if (!content.includes(pgHba))
329
329
  throw 'missing.';
330
- opt.output('done');
331
- opt.output('start', 'Removing Axium HBA configuration');
330
+ io.done();
331
+ io.start('Removing Axium HBA configuration');
332
332
  const newContent = content.replace(pgHba, '');
333
- opt.output('done');
333
+ io.done();
334
334
  writeBack(newContent);
335
335
  })
336
- .catch(e => opt.output('warn', e));
336
+ .catch(io.warn);
337
337
  }
338
338
  catch (e_3) {
339
339
  env_3.error = e_3;
@@ -349,17 +349,16 @@ export async function uninstall(opt) {
349
349
  * Removes all data from tables.
350
350
  */
351
351
  export async function wipe(opt) {
352
- _fixOutput(opt);
353
352
  const db = connect();
354
353
  for (const plugin of plugins) {
355
- if (!plugin.db_wipe)
354
+ if (!plugin.hooks.db_wipe)
356
355
  continue;
357
- opt.output('plugin', plugin.name);
358
- await plugin.db_wipe(opt, db);
356
+ io.plugin(plugin.name);
357
+ await plugin.hooks.db_wipe(opt, db);
359
358
  }
360
359
  for (const table of ['users', 'passkeys', 'sessions', 'verifications']) {
361
- opt.output('start', `Removing data from ${table}`);
360
+ io.start(`Removing data from ${table}`);
362
361
  await db.deleteFrom(table).execute();
363
- opt.output('done');
362
+ io.done();
364
363
  }
365
364
  }
package/dist/io.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Logger } from 'logzen';
2
+ export declare const systemDir = "/etc/axium";
3
+ export declare const userDir: string;
4
+ export declare const dirs: string[];
5
+ export declare const logger: Logger;
2
6
  /**
3
- * Find the Axium directory.
4
- * This directory includes things like config files, secrets, etc.
7
+ * @internal
5
8
  */
6
- export declare function findDir(global: boolean): string;
7
- export declare const logger: Logger;
8
9
  export declare const output: {
9
10
  constructor: {
10
11
  name: string;
@@ -15,13 +16,12 @@ export declare const output: {
15
16
  log(message: string): void;
16
17
  debug(message: string): void;
17
18
  };
19
+ export declare function setCommandTimeout(value: number): void;
18
20
  /**
19
21
  * Run a system command with the fancy "Example... done."
20
22
  * @internal
21
23
  */
22
- export declare function run(opts: WithOutput & {
23
- timeout?: number;
24
- }, message: string, command: string): Promise<string>;
24
+ export declare function run(message: string, command: string): Promise<string>;
25
25
  /** Yet another convenience function */
26
26
  export declare function exit(message: string | Error, code?: number): never;
27
27
  export declare function handleError(e: number | string | Error): void;
@@ -30,19 +30,18 @@ export interface Output {
30
30
  (tag: 'done'): void;
31
31
  (tag: Exclude<OutputTag, 'done'>, message: string): void;
32
32
  }
33
- export interface MaybeOutput {
34
- output?: Output | null | false;
35
- }
36
- export interface WithOutput {
37
- output: Output;
38
- }
39
- export declare function defaultOutput(tag: 'done'): void;
40
- export declare function defaultOutput(tag: Exclude<OutputTag, 'done'>, message: string): void;
41
33
  /**
42
- * TS can't tell when we do this inline
43
- * @internal
34
+ * Enable or disable debug output.
44
35
  */
45
- export declare function _fixOutput<T extends MaybeOutput>(opt: T): asserts opt is T & WithOutput;
36
+ export declare function _setDebugOutput(enabled: boolean): void;
37
+ export declare function useTaggedOutput(output: Output | null): void;
38
+ export declare function done(): void;
39
+ export declare function start(message: string): void;
40
+ export declare function plugin(name: string): void;
41
+ export declare function debug(message: string): void;
42
+ export declare function info(message: string): void;
43
+ export declare function warn(message: string): void;
44
+ export declare function error(message: string): void;
46
45
  /** @internal */
47
46
  export declare const _portMethods: readonly ["node-cap"];
48
47
  /** @internal */
@@ -53,7 +52,7 @@ export declare const _portActions: readonly ["enable", "disable"];
53
52
  * Method:
54
53
  * - `node-cap`: Use the `cap_net_bind_service` capability on the node binary.
55
54
  */
56
- export interface PortOptions extends MaybeOutput {
55
+ export interface PortOptions {
57
56
  method: (typeof _portMethods)[number];
58
57
  action: (typeof _portActions)[number];
59
58
  node?: string;
@@ -69,4 +68,4 @@ export declare function restrictedPorts(opt: PortOptions): Promise<void>;
69
68
  * The handler will allow the parent scope to continue if a relation already exists,
70
69
  * rather than fatally exiting.
71
70
  */
72
- export declare function someWarnings(output: Output, ...allowList: [RegExp, string?][]): (error: string | Error) => void;
71
+ export declare function someWarnings(...allowList: [RegExp, string?][]): (error: string | Error) => void;