@logto/cli 1.0.3 → 1.2.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 (45) hide show
  1. package/lib/commands/connector/add.js +4 -4
  2. package/lib/commands/connector/index.js +2 -0
  3. package/lib/commands/connector/link.d.ts +9 -0
  4. package/lib/commands/connector/link.js +46 -0
  5. package/lib/commands/connector/list.js +4 -3
  6. package/lib/commands/connector/remove.js +7 -7
  7. package/lib/commands/connector/utils.d.ts +2 -0
  8. package/lib/commands/connector/utils.js +29 -17
  9. package/lib/commands/database/alteration/index.js +8 -8
  10. package/lib/commands/database/alteration/utils.js +3 -3
  11. package/lib/commands/database/alteration/version.js +4 -4
  12. package/lib/commands/database/config.js +11 -11
  13. package/lib/commands/database/seed/cloud.js +2 -2
  14. package/lib/commands/database/seed/index.js +4 -5
  15. package/lib/commands/database/seed/oidc-config.js +6 -6
  16. package/lib/commands/database/seed/tables.js +4 -4
  17. package/lib/commands/database/seed/tenant.js +2 -2
  18. package/lib/commands/database/system.js +5 -5
  19. package/lib/commands/database/utils.js +3 -3
  20. package/lib/commands/install/index.js +3 -3
  21. package/lib/commands/install/utils.js +17 -17
  22. package/lib/commands/translate/create.d.ts +8 -0
  23. package/lib/commands/translate/create.js +38 -0
  24. package/lib/commands/translate/index.d.ts +3 -0
  25. package/lib/commands/translate/index.js +20 -0
  26. package/lib/commands/translate/list-tags.d.ts +3 -0
  27. package/lib/commands/translate/list-tags.js +19 -0
  28. package/lib/commands/translate/openai.d.ts +11 -0
  29. package/lib/commands/translate/openai.js +77 -0
  30. package/lib/commands/translate/prompts.d.ts +14 -0
  31. package/lib/commands/translate/prompts.js +39 -0
  32. package/lib/commands/translate/sync.d.ts +7 -0
  33. package/lib/commands/translate/sync.js +40 -0
  34. package/lib/commands/translate/utils.d.ts +14 -0
  35. package/lib/commands/translate/utils.js +131 -0
  36. package/lib/connector/factories.js +2 -1
  37. package/lib/connector/loader.js +5 -4
  38. package/lib/connector/utils.js +3 -3
  39. package/lib/database.js +3 -3
  40. package/lib/index.js +4 -2
  41. package/lib/package-json.d.ts +7 -0
  42. package/lib/package-json.js +14 -7
  43. package/lib/utils.d.ts +3 -8
  44. package/lib/utils.js +23 -24
  45. package/package.json +15 -8
@@ -1,4 +1,4 @@
1
- import { log } from '../../utils.js';
1
+ import { consoleLog } from '../../utils.js';
2
2
  import { addConnectors, addOfficialConnectors, inquireInstancePath } from './utils.js';
3
3
  const add = {
4
4
  command: ['add [packages...]', 'a', 'install', 'i'],
@@ -26,7 +26,7 @@ const add = {
26
26
  handler: async ({ packages: packageNames, path, official, cloud }) => {
27
27
  const instancePath = await inquireInstancePath(path);
28
28
  if (cloud && !official) {
29
- log.error('--cloud option can only be used with --official option');
29
+ consoleLog.fatal('--cloud option can only be used with --official option');
30
30
  }
31
31
  if (official) {
32
32
  // Add demo connectors for Logto Cloud only
@@ -34,11 +34,11 @@ const add = {
34
34
  }
35
35
  else {
36
36
  if (!packageNames?.length) {
37
- log.error('No connector name provided');
37
+ consoleLog.fatal('No connector name provided');
38
38
  }
39
39
  await addConnectors(instancePath, packageNames);
40
40
  }
41
- log.info('Restart your Logto instance to get the changes reflected.');
41
+ consoleLog.info('Restart your Logto instance to get the changes reflected.');
42
42
  },
43
43
  };
44
44
  export default add;
@@ -1,5 +1,6 @@
1
1
  import { noop } from '@silverhand/essentials';
2
2
  import add from './add.js';
3
+ import link from './link.js';
3
4
  import list from './list.js';
4
5
  import remove from './remove.js';
5
6
  const connector = {
@@ -14,6 +15,7 @@ const connector = {
14
15
  .command(add)
15
16
  .command(list)
16
17
  .command(remove)
18
+ .command(link)
17
19
  .demandCommand(1),
18
20
  handler: noop,
19
21
  };
@@ -0,0 +1,9 @@
1
+ import type { CommandModule } from 'yargs';
2
+ declare const link: CommandModule<{
3
+ path?: string;
4
+ }, {
5
+ path?: string;
6
+ cloud: boolean;
7
+ mock: boolean;
8
+ }>;
9
+ export default link;
@@ -0,0 +1,46 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { consoleLog } from '../../utils.js';
4
+ import { getConnectorDirectory, getLocalConnectorPackages, inquireInstancePath } from './utils.js';
5
+ const link = {
6
+ command: ['link', 'ln'],
7
+ describe: 'Link all connectors in `packages/connectors`, useful for adding local connectors.',
8
+ builder: (yargs) => yargs
9
+ .option('cloud', {
10
+ describe: 'Add additional connectors for Logto Cloud',
11
+ type: 'boolean',
12
+ default: false,
13
+ hidden: true,
14
+ })
15
+ .option('mock', {
16
+ describe: 'Add mock connectors',
17
+ type: 'boolean',
18
+ default: false,
19
+ hidden: true,
20
+ }),
21
+ handler: async ({ path: inputPath, cloud, mock }) => {
22
+ const instancePath = await inquireInstancePath(inputPath);
23
+ const packages = await getLocalConnectorPackages(instancePath);
24
+ const connectorDirectory = getConnectorDirectory(instancePath);
25
+ await fs.mkdir(connectorDirectory, { recursive: true });
26
+ await Promise.all(packages.map(async ([packageName, packagePath]) => {
27
+ if (!cloud && packageName.startsWith('connector-logto-')) {
28
+ return;
29
+ }
30
+ if (!mock && packageName.startsWith('connector-mock-')) {
31
+ return;
32
+ }
33
+ try {
34
+ const targetPath = path.join(connectorDirectory, '@logto-' + packageName);
35
+ await fs.rm(targetPath, { recursive: true, force: true });
36
+ await fs.symlink(path.relative(connectorDirectory, packagePath), targetPath);
37
+ }
38
+ catch (error) {
39
+ consoleLog.warn(error);
40
+ return;
41
+ }
42
+ consoleLog.succeed('Linked', packagePath);
43
+ }));
44
+ },
45
+ };
46
+ export default link;
@@ -1,12 +1,13 @@
1
1
  import chalk from 'chalk';
2
+ import { consoleLog } from '../../utils.js';
2
3
  import { getConnectorPackagesFrom, isOfficialConnector } from './utils.js';
3
4
  const logConnectorNames = (type, packages) => {
4
5
  if (packages.length === 0) {
5
6
  return;
6
7
  }
7
- console.log();
8
- console.log(chalk.blue(type));
9
- console.log(packages.map(({ name }) => ' ' + name).join('\n'));
8
+ consoleLog.plain();
9
+ consoleLog.plain(chalk.blue(type));
10
+ consoleLog.plain(packages.map(({ name }) => ' ' + name).join('\n'));
10
11
  };
11
12
  const list = {
12
13
  command: ['list', 'l'],
@@ -1,6 +1,6 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
  import chalk from 'chalk';
3
- import { log } from '../../utils.js';
3
+ import { consoleLog } from '../../utils.js';
4
4
  import { getConnectorPackagesFrom } from './utils.js';
5
5
  const remove = {
6
6
  command: ['remove [packages...]', 'rm', 'delete'],
@@ -13,12 +13,12 @@ const remove = {
13
13
  }),
14
14
  handler: async ({ path: inputPath, packages: packageNames }) => {
15
15
  if (!packageNames?.length) {
16
- log.error('No connector name provided');
16
+ consoleLog.fatal('No connector name provided');
17
17
  }
18
18
  const existingPackages = await getConnectorPackagesFrom(inputPath);
19
19
  const notFoundPackageNames = packageNames.filter((current) => !existingPackages.some(({ name }) => current === name));
20
20
  if (notFoundPackageNames.length > 0) {
21
- log.error(`Cannot remove ${notFoundPackageNames
21
+ consoleLog.fatal(`Cannot remove ${notFoundPackageNames
22
22
  .map((name) => chalk.green(name))
23
23
  .join(', ')}: not found in your Logto instance directory`);
24
24
  }
@@ -30,13 +30,13 @@ const remove = {
30
30
  return okSymbol;
31
31
  }
32
32
  catch (error) {
33
- log.warn(`Error while removing ${chalk.green(packageInfo?.name)}`);
34
- log.warn(error);
33
+ consoleLog.warn(`Error while removing ${chalk.green(packageInfo?.name)}`);
34
+ consoleLog.warn(error);
35
35
  return error;
36
36
  }
37
37
  }));
38
38
  const errorCount = result.filter((value) => value !== okSymbol).length;
39
- log.info(`Removed ${result.length - errorCount} connectors`);
39
+ consoleLog.info(`Removed ${result.length - errorCount} connectors`);
40
40
  },
41
41
  };
42
42
  export default remove;
@@ -14,7 +14,9 @@ export declare const npmPackResultGuard: z.ZodArray<z.ZodObject<{
14
14
  }>, "many">;
15
15
  export declare const inquireInstancePath: (initialPath?: string) => Promise<string>;
16
16
  export declare const normalizePackageName: (name: string) => string;
17
+ export declare const getConnectorDirectory: (instancePath: string) => string;
17
18
  export declare const isOfficialConnector: (packageName: string) => boolean;
18
19
  export declare const getConnectorPackagesFrom: (instancePath?: string) => Promise<import("../../utils.js").ConnectorPackage[]>;
20
+ export declare const getLocalConnectorPackages: (instancePath: string) => Promise<(readonly [string, string])[]>;
19
21
  export declare const addConnectors: (instancePath: string, packageNames: string[]) => Promise<void>;
20
22
  export declare const addOfficialConnectors: (instancePath: string, includingCloudConnectors?: boolean) => Promise<void>;
@@ -1,9 +1,9 @@
1
- import { exec } from 'child_process';
2
- import { existsSync } from 'fs';
3
- import fs from 'fs/promises';
4
- import path from 'path';
5
- import { promisify } from 'util';
6
- import { assert, conditionalString, trySafe } from '@silverhand/essentials';
1
+ import { exec } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { promisify } from 'node:util';
6
+ import { assert, conditionalArray, conditionalString, trySafe } from '@silverhand/essentials';
7
7
  import chalk from 'chalk';
8
8
  import { got } from 'got';
9
9
  import inquirer from 'inquirer';
@@ -12,7 +12,7 @@ import pRetry from 'p-retry';
12
12
  import tar from 'tar';
13
13
  import { z } from 'zod';
14
14
  import { connectorDirectory } from '../../constants.js';
15
- import { getConnectorPackagesFromDirectory, isTty, log, oraPromise } from '../../utils.js';
15
+ import { consoleLog, getConnectorPackagesFromDirectory, isTty, oraPromise } from '../../utils.js';
16
16
  import { defaultPath } from '../install/utils.js';
17
17
  const coreDirectory = 'packages/core';
18
18
  const execPromise = promisify(exec);
@@ -42,6 +42,9 @@ const validatePath = async (value) => {
42
42
  };
43
43
  export const inquireInstancePath = async (initialPath) => {
44
44
  const inquire = async () => {
45
+ if (!initialPath && (await validatePath('.')) === true) {
46
+ return path.resolve('.');
47
+ }
45
48
  if (!isTty()) {
46
49
  assert(initialPath, new Error('Path is missing'));
47
50
  return initialPath;
@@ -59,7 +62,7 @@ export const inquireInstancePath = async (initialPath) => {
59
62
  const instancePath = await inquire();
60
63
  const validated = await validatePath(instancePath);
61
64
  if (validated !== true) {
62
- log.error(validated);
65
+ consoleLog.fatal(validated);
63
66
  }
64
67
  return instancePath;
65
68
  };
@@ -71,22 +74,31 @@ export const normalizePackageName = (name) => name
71
74
  ? packagePrefix + fragment
72
75
  : fragment)
73
76
  .join('/');
74
- const getConnectorDirectory = (instancePath) => path.join(instancePath, coreDirectory, connectorDirectory);
77
+ export const getConnectorDirectory = (instancePath) => path.join(instancePath, coreDirectory, connectorDirectory);
75
78
  export const isOfficialConnector = (packageName) => packageName.startsWith('@logto/connector-');
76
79
  export const getConnectorPackagesFrom = async (instancePath) => {
77
80
  const directory = getConnectorDirectory(await inquireInstancePath(instancePath));
78
81
  const packages = await trySafe(getConnectorPackagesFromDirectory(directory));
79
82
  if (!packages || packages.length === 0) {
80
- throw new Error('No connector found');
83
+ throw new Error('No connector found in ' + directory);
81
84
  }
82
85
  return packages;
83
86
  };
87
+ export const getLocalConnectorPackages = async (instancePath) => {
88
+ const directory = path.join(instancePath, 'packages', connectorDirectory);
89
+ const files = await fs.readdir(directory, { withFileTypes: true });
90
+ const packages = files.filter((entity) => entity.isDirectory() && entity.name.startsWith('connector-'));
91
+ if (packages.length === 0) {
92
+ throw new Error('No connector found in ' + directory);
93
+ }
94
+ return packages.map(({ name }) => [name, path.join(directory, name)]);
95
+ };
84
96
  export const addConnectors = async (instancePath, packageNames) => {
85
97
  const cwd = getConnectorDirectory(instancePath);
86
98
  if (!existsSync(cwd)) {
87
99
  await fs.mkdir(cwd, { recursive: true });
88
100
  }
89
- log.info('Fetch connector metadata');
101
+ consoleLog.info('Fetch connector metadata');
90
102
  const limit = pLimit(10);
91
103
  const results = await Promise.all(packageNames
92
104
  .map((name) => normalizePackageName(name))
@@ -105,25 +117,25 @@ export const addConnectors = async (instancePath, packageNames) => {
105
117
  await fs.mkdir(packageDirectory, { recursive: true });
106
118
  await tar.extract({ cwd: packageDirectory, file: tarPath, strip: 1 });
107
119
  await fs.unlink(tarPath);
108
- log.succeed(`Added ${chalk.green(name)} v${version}`);
120
+ consoleLog.succeed(`Added ${chalk.green(name)} v${version}`);
109
121
  };
110
122
  return limit(async () => {
111
123
  try {
112
124
  await pRetry(run, { retries: 2 });
113
125
  }
114
126
  catch (error) {
115
- console.warn(`[${packageName}]`, error);
127
+ consoleLog.error(`[${packageName}]`, error);
116
128
  return packageName;
117
129
  }
118
130
  });
119
131
  }));
120
132
  const errorPackages = results.filter(Boolean);
121
133
  const errorCount = errorPackages.length;
122
- log.info(errorCount
134
+ consoleLog.info(errorCount
123
135
  ? `Finished with ${errorCount} error${conditionalString(errorCount > 1 && 's')}.`
124
136
  : 'Finished');
125
137
  if (errorCount) {
126
- log.warn('Failed to add ' + errorPackages.map((name) => chalk.green(name)).join(', '));
138
+ consoleLog.warn('Failed to add ' + errorPackages.map((name) => chalk.green(name)).join(', '));
127
139
  }
128
140
  };
129
141
  const officialConnectorPrefix = '@logto/connector-';
@@ -142,7 +154,7 @@ const fetchOfficialConnectorList = async (includingCloudConnectors = false) => {
142
154
  for (let page = 0;; ++page) {
143
155
  // eslint-disable-next-line no-await-in-loop
144
156
  const { objects } = await fetchList(page * 20, 20);
145
- const excludeList = ['mock', 'kit', ...(includingCloudConnectors ? [] : ['logto'])];
157
+ const excludeList = ['mock', 'kit', ...conditionalArray(!includingCloudConnectors && 'logto')];
146
158
  // eslint-disable-next-line @silverhand/fp/no-mutating-methods
147
159
  packages.push(...objects
148
160
  .filter(({ package: { name, scope } }) => scope === 'logto' &&
@@ -159,6 +171,6 @@ export const addOfficialConnectors = async (instancePath, includingCloudConnecto
159
171
  text: 'Fetch official connector list',
160
172
  prefixText: chalk.blue('[info]'),
161
173
  });
162
- log.info(`Found ${packages.length} official connectors`);
174
+ consoleLog.info(`Found ${packages.length} official connectors`);
163
175
  await addConnectors(instancePath, packages.map(({ name }) => name));
164
176
  };
@@ -2,7 +2,7 @@ import { conditionalString } from '@silverhand/essentials';
2
2
  import chalk from 'chalk';
3
3
  import { createPoolFromConfig } from '../../../database.js';
4
4
  import { getCurrentDatabaseAlterationTimestamp, updateDatabaseTimestamp, } from '../../../queries/system.js';
5
- import { log } from '../../../utils.js';
5
+ import { consoleLog } from '../../../utils.js';
6
6
  import { getAlterationFiles, getTimestampFromFilename } from './utils.js';
7
7
  import { chooseAlterationsByVersion, chooseRevertAlterationsByVersion } from './version.js';
8
8
  const importAlterationScript = async (filePath) => {
@@ -44,13 +44,13 @@ const deployAlteration = async (pool, { path: filePath, filename }, action = 'up
44
44
  });
45
45
  }
46
46
  catch (error) {
47
- console.error(error);
47
+ consoleLog.error(error);
48
48
  await pool.end();
49
- log.error(`Error ocurred during running alteration ${chalk.blue(filename)}.\n\n` +
49
+ consoleLog.fatal(`Error ocurred during running alteration ${chalk.blue(filename)}.\n\n` +
50
50
  " This alteration didn't change anything since it was in a transaction.\n" +
51
51
  ' Try to fix the error and deploy again.');
52
52
  }
53
- log.info(`Run alteration ${filename} \`${action}()\` function succeeded`);
53
+ consoleLog.info(`Run alteration ${filename} \`${action}()\` function succeeded`);
54
54
  };
55
55
  const alteration = {
56
56
  command: ['alteration <action> [target]', 'alt', 'alter'],
@@ -69,13 +69,13 @@ const alteration = {
69
69
  if (action === 'list') {
70
70
  const files = await getAlterationFiles();
71
71
  for (const file of files) {
72
- console.log(file.filename);
72
+ consoleLog.plain(file.filename);
73
73
  }
74
74
  }
75
75
  else if (action === 'deploy') {
76
76
  const pool = await createPoolFromConfig();
77
77
  const alterations = await chooseAlterationsByVersion(await getAvailableAlterations(pool), target);
78
- log.info(`Found ${alterations.length} alteration${conditionalString(alterations.length > 1 && 's')} to deploy`);
78
+ consoleLog.info(`Found ${alterations.length} alteration${conditionalString(alterations.length > 1 && 's')} to deploy`);
79
79
  // The await inside the loop is intended, alterations should run in order
80
80
  for (const alteration of alterations) {
81
81
  // eslint-disable-next-line no-await-in-loop
@@ -86,7 +86,7 @@ const alteration = {
86
86
  else if (['rollback', 'r'].includes(action)) {
87
87
  const pool = await createPoolFromConfig();
88
88
  const alterations = await chooseRevertAlterationsByVersion(await getAvailableAlterations(pool, 'lte'), target ?? '');
89
- log.info(`Found ${alterations.length} alteration${conditionalString(alterations.length > 1 && 's')} to revert`);
89
+ consoleLog.info(`Found ${alterations.length} alteration${conditionalString(alterations.length > 1 && 's')} to revert`);
90
90
  // The await inside the loop is intended, alterations should run in order
91
91
  // eslint-disable-next-line @silverhand/fp/no-mutating-methods
92
92
  for (const alteration of alterations.slice().reverse()) {
@@ -96,7 +96,7 @@ const alteration = {
96
96
  await pool.end();
97
97
  }
98
98
  else {
99
- log.error('Unsupported action');
99
+ consoleLog.fatal('Unsupported action');
100
100
  }
101
101
  },
102
102
  };
@@ -1,7 +1,7 @@
1
- import { existsSync } from 'fs';
2
- import fs from 'fs/promises';
1
+ import { existsSync } from 'node:fs';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
3
4
  import { fileURLToPath } from 'node:url';
4
- import path from 'path';
5
5
  import { findPackage } from '@logto/shared';
6
6
  import { getPathInModule } from '../../../utils.js';
7
7
  const currentDirname = path.dirname(fileURLToPath(import.meta.url));
@@ -2,7 +2,7 @@ import { assert, conditional } from '@silverhand/essentials';
2
2
  import chalk from 'chalk';
3
3
  import inquirer from 'inquirer';
4
4
  import { SemVer, compare, eq, gt } from 'semver';
5
- import { findLastIndex, isTty, log } from '../../../utils.js';
5
+ import { consoleLog, findLastIndex, isTty } from '../../../utils.js';
6
6
  const getVersionStringFromFilename = (filename) => filename.split('-')[0]?.replaceAll('_', '-') ?? 'unknown';
7
7
  const getVersionFromFilename = (filename) => {
8
8
  try {
@@ -25,7 +25,7 @@ export const chooseAlterationsByVersion = async (alterations, initialVersion) =>
25
25
  if (endIndex === -1) {
26
26
  return [];
27
27
  }
28
- log.info(`Deploy target ${chalk.green(nextTag)}`);
28
+ consoleLog.info(`Deploy target ${chalk.green(nextTag)}`);
29
29
  return alterations.slice(0, endIndex + 1);
30
30
  }
31
31
  const versions = getAlterationVersions(alterations);
@@ -56,7 +56,7 @@ export const chooseAlterationsByVersion = async (alterations, initialVersion) =>
56
56
  return version;
57
57
  };
58
58
  const targetVersion = await getTargetVersion();
59
- log.info(`Deploy target ${chalk.green(targetVersion.version)}`);
59
+ consoleLog.info(`Deploy target ${chalk.green(targetVersion.version)}`);
60
60
  return alterations.filter(({ filename }) => {
61
61
  const version = getVersionFromFilename(filename);
62
62
  return version && !gt(version, targetVersion);
@@ -64,7 +64,7 @@ export const chooseAlterationsByVersion = async (alterations, initialVersion) =>
64
64
  };
65
65
  export const chooseRevertAlterationsByVersion = async (alterations, version) => {
66
66
  const semVersion = new SemVer(version);
67
- log.info(`Revert target ${chalk.green(semVersion.version)}`);
67
+ consoleLog.info(`Revert target ${chalk.green(semVersion.version)}`);
68
68
  return alterations.filter(({ filename }) => {
69
69
  if (getVersionStringFromFilename(filename) === nextTag) {
70
70
  return true;
@@ -3,7 +3,7 @@ import { deduplicate, noop } from '@silverhand/essentials';
3
3
  import chalk from 'chalk';
4
4
  import { createPoolFromConfig } from '../../database.js';
5
5
  import { getRowsByKeys, updateValueByKey } from '../../queries/logto-config.js';
6
- import { log } from '../../utils.js';
6
+ import { consoleLog } from '../../utils.js';
7
7
  import { generateOidcCookieKey, generateOidcPrivateKey } from './utils.js';
8
8
  const validKeysDisplay = chalk.green(logtoConfigKeys.join(', '));
9
9
  const validateKeys = (keys) => {
@@ -12,7 +12,7 @@ const validateKeys = (keys) => {
12
12
  // eslint-disable-next-line unicorn/prefer-includes
13
13
  (key) => !logtoConfigKeys.some((element) => element === key));
14
14
  if (invalidKey) {
15
- log.error(`Invalid config key ${chalk.red(invalidKey)} found, expected one of ${validKeysDisplay}`);
15
+ consoleLog.fatal(`Invalid config key ${chalk.red(invalidKey)} found, expected one of ${validKeysDisplay}`);
16
16
  }
17
17
  };
18
18
  const validRotateKeys = Object.freeze([
@@ -23,7 +23,7 @@ const validateRotateKey = (key) => {
23
23
  // Using `.includes()` will result a type error
24
24
  // eslint-disable-next-line unicorn/prefer-includes
25
25
  if (!validRotateKeys.some((element) => element === key)) {
26
- log.error(`Invalid config key ${chalk.red(key)} found, expected one of ${validKeysDisplay}`);
26
+ consoleLog.fatal(`Invalid config key ${chalk.red(key)} found, expected one of ${validKeysDisplay}`);
27
27
  }
28
28
  };
29
29
  const getConfig = {
@@ -52,7 +52,7 @@ const getConfig = {
52
52
  const pool = await createPoolFromConfig();
53
53
  const { rows } = await getRowsByKeys(pool, tenantId, queryKeys);
54
54
  await pool.end();
55
- console.log(queryKeys
55
+ consoleLog.plain(queryKeys
56
56
  .map((currentKey) => {
57
57
  const value = rows.find(({ key }) => currentKey === key)?.value;
58
58
  return (chalk.magenta(currentKey) +
@@ -87,7 +87,7 @@ const setConfig = {
87
87
  const pool = await createPoolFromConfig();
88
88
  await updateValueByKey(pool, tenantId, key, guarded);
89
89
  await pool.end();
90
- log.info(`Update ${chalk.green(key)} succeeded`);
90
+ consoleLog.info(`Update ${chalk.green(key)} succeeded`);
91
91
  },
92
92
  };
93
93
  const rotateConfig = {
@@ -109,7 +109,7 @@ const rotateConfig = {
109
109
  const pool = await createPoolFromConfig();
110
110
  const { rows } = await getRowsByKeys(pool, tenantId, [key]);
111
111
  if (!rows[0]) {
112
- log.warn('No key found, create a new one');
112
+ consoleLog.warn('No key found, create a new one');
113
113
  }
114
114
  const getValue = async () => {
115
115
  const parsed = logtoConfigGuards[key].safeParse(rows[0]?.value);
@@ -127,7 +127,7 @@ const rotateConfig = {
127
127
  const rotated = await getValue();
128
128
  await updateValueByKey(pool, tenantId, key, rotated);
129
129
  await pool.end();
130
- log.info(`Rotate ${chalk.green(key)} succeeded, now it has ${rotated.length} keys`);
130
+ consoleLog.info(`Rotate ${chalk.green(key)} succeeded, now it has ${rotated.length} keys`);
131
131
  },
132
132
  };
133
133
  const trimConfig = {
@@ -153,25 +153,25 @@ const trimConfig = {
153
153
  handler: async ({ key, length, tenantId }) => {
154
154
  validateRotateKey(key);
155
155
  if (length < 1) {
156
- log.error('Invalid length provided');
156
+ consoleLog.fatal('Invalid length provided');
157
157
  }
158
158
  const pool = await createPoolFromConfig();
159
159
  const { rows } = await getRowsByKeys(pool, tenantId, [key]);
160
160
  if (!rows[0]) {
161
- log.warn('No key found, create a new one');
161
+ consoleLog.warn('No key found, create a new one');
162
162
  }
163
163
  const getValue = async () => {
164
164
  const value = logtoConfigGuards[key].parse(rows[0]?.value);
165
165
  if (value.length - length < 1) {
166
166
  await pool.end();
167
- log.error(`You should keep at least one key in the array, current length=${value.length}`);
167
+ consoleLog.fatal(`You should keep at least one key in the array, current length=${value.length}`);
168
168
  }
169
169
  return value.slice(0, -length);
170
170
  };
171
171
  const trimmed = await getValue();
172
172
  await updateValueByKey(pool, tenantId, key, trimmed);
173
173
  await pool.end();
174
- log.info(`Trim ${chalk.green(key)} succeeded, now it has ${trimmed.length} keys`);
174
+ consoleLog.info(`Trim ${chalk.green(key)} succeeded, now it has ${trimmed.length} keys`);
175
175
  },
176
176
  };
177
177
  const config = {
@@ -2,7 +2,7 @@ import { adminConsoleApplicationId, adminTenantId, defaultTenantId } from '@logt
2
2
  import { GlobalValues } from '@logto/shared';
3
3
  import { appendPath } from '@silverhand/essentials';
4
4
  import { sql } from 'slonik';
5
- import { log } from '../../../utils.js';
5
+ import { consoleLog } from '../../../utils.js';
6
6
  /**
7
7
  * Append Redirect URIs for the default tenant callback in cloud Admin Console.
8
8
  * It reads the same env variables as core to construct the cloud `UrlSet`.
@@ -30,5 +30,5 @@ export const appendAdminConsoleRedirectUris = async (pool) => {
30
30
  where id = ${adminConsoleApplicationId}
31
31
  and tenant_id = ${adminTenantId}
32
32
  `);
33
- log.succeed('Appended initial Redirect URIs to Admin Console:', redirectUris.map(String));
33
+ consoleLog.succeed('Appended initial Redirect URIs to Admin Console:', redirectUris.map(String));
34
34
  };
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
  import { createPoolAndDatabaseIfNeeded } from '../../../database.js';
3
3
  import { doesConfigsTableExist } from '../../../queries/logto-config.js';
4
- import { log, oraPromise } from '../../../utils.js';
4
+ import { consoleLog, oraPromise } from '../../../utils.js';
5
5
  import { getLatestAlterationTimestamp } from '../alteration/index.js';
6
6
  import { getAlterationDirectory } from '../alteration/utils.js';
7
7
  import { createTables, seedCloud, seedTables } from './tables.js';
@@ -40,7 +40,7 @@ const seed = {
40
40
  handler: async ({ swe, cloud }) => {
41
41
  const pool = await createPoolAndDatabaseIfNeeded();
42
42
  if (swe && (await doesConfigsTableExist(pool))) {
43
- log.info('Seeding skipped');
43
+ consoleLog.info('Seeding skipped');
44
44
  await pool.end();
45
45
  return;
46
46
  }
@@ -48,9 +48,8 @@ const seed = {
48
48
  await seedByPool(pool, cloud);
49
49
  }
50
50
  catch (error) {
51
- console.error(error);
52
- console.log();
53
- log.warn('Error ocurred during seeding your database.\n\n' +
51
+ consoleLog.error(error);
52
+ consoleLog.error('Error ocurred during seeding your database.\n\n' +
54
53
  ' Nothing has changed since the seeding process was in a transaction.\n' +
55
54
  ' Try to fix the error and seed again.');
56
55
  }
@@ -1,10 +1,10 @@
1
- import { readFile } from 'fs/promises';
1
+ import { readFile } from 'node:fs/promises';
2
2
  import { LogtoOidcConfigKey, logtoConfigGuards } from '@logto/schemas';
3
3
  import { getEnvAsStringArray } from '@silverhand/essentials';
4
4
  import chalk from 'chalk';
5
5
  import { z } from 'zod';
6
6
  import { getRowsByKeys, updateValueByKey } from '../../../queries/logto-config.js';
7
- import { log } from '../../../utils.js';
7
+ import { consoleLog } from '../../../utils.js';
8
8
  import { generateOidcCookieKey, generateOidcPrivateKey } from '../utils.js';
9
9
  const isBase64FormatPrivateKey = (key) => !key.includes('-');
10
10
  export const seedOidcConfigs = async (pool, tenantId) => {
@@ -27,7 +27,7 @@ export const seedOidcConfigs = async (pool, tenantId) => {
27
27
  const validOptions = Object.values(LogtoOidcConfigKey).filter((key) => {
28
28
  const included = existingKeys.has(key);
29
29
  if (included) {
30
- log.info(tenantPrefix, `Key ${chalk.green(key)} exists, skipping`);
30
+ consoleLog.info(tenantPrefix, `Key ${chalk.green(key)} exists, skipping`);
31
31
  }
32
32
  return !included;
33
33
  });
@@ -36,15 +36,15 @@ export const seedOidcConfigs = async (pool, tenantId) => {
36
36
  for (const key of validOptions) {
37
37
  const { value, fromEnv } = await oidcConfigReaders[key]();
38
38
  if (fromEnv) {
39
- log.info(tenantPrefix, `Read config ${chalk.green(key)} from env`);
39
+ consoleLog.info(tenantPrefix, `Read config ${chalk.green(key)} from env`);
40
40
  }
41
41
  else {
42
- log.info(tenantPrefix, `Generated config ${chalk.green(key)}`);
42
+ consoleLog.info(tenantPrefix, `Generated config ${chalk.green(key)}`);
43
43
  }
44
44
  await updateValueByKey(pool, tenantId, key, value);
45
45
  }
46
46
  /* eslint-enable no-await-in-loop */
47
- log.succeed(tenantPrefix, 'Seed OIDC config');
47
+ consoleLog.succeed(tenantPrefix, 'Seed OIDC config');
48
48
  };
49
49
  /**
50
50
  * Each config reader will do the following things in order:
@@ -1,5 +1,5 @@
1
- import { readdir, readFile } from 'fs/promises';
2
- import path from 'path';
1
+ import { readdir, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
3
  import { createDefaultAdminConsoleConfig, defaultTenantId, adminTenantId, defaultManagementApi, createAdminDataInAdminTenant, createMeApiInAdminTenant, createDefaultSignInExperience, createAdminTenantSignInExperience, createDefaultAdminConsoleApplication, createCloudApi, createTenantApplicationRole, createTenantMachineToMachineApplication, createAdminTenantApplicationRole, CloudScope, } from '@logto/schemas';
4
4
  import { Tenants } from '@logto/schemas/models';
5
5
  import { sql } from 'slonik';
@@ -7,7 +7,7 @@ import { raw } from 'slonik-sql-tag-raw';
7
7
  import { insertInto } from '../../../database.js';
8
8
  import { getDatabaseName } from '../../../queries/database.js';
9
9
  import { updateDatabaseTimestamp } from '../../../queries/system.js';
10
- import { getPathInModule, log } from '../../../utils.js';
10
+ import { consoleLog, getPathInModule } from '../../../utils.js';
11
11
  import { appendAdminConsoleRedirectUris } from './cloud.js';
12
12
  import { seedOidcConfigs } from './oidc-config.js';
13
13
  import { assignScopesToRole, createTenant, seedAdminData } from './tenant.js';
@@ -102,7 +102,7 @@ export const seedTables = async (connection, latestTimestamp, isCloud) => {
102
102
  connection.query(insertInto(createDefaultAdminConsoleApplication(), 'applications')),
103
103
  updateDatabaseTimestamp(connection, latestTimestamp),
104
104
  ]);
105
- log.succeed('Seed data');
105
+ consoleLog.succeed('Seed data');
106
106
  };
107
107
  export const seedCloud = async (connection) => {
108
108
  await appendAdminConsoleRedirectUris(connection);
@@ -1,5 +1,5 @@
1
- import { generateStandardId } from '@logto/core-kit';
2
- import { createTenantMetadata } from '@logto/shared';
1
+ import { createTenantMetadata } from '@logto/core-kit';
2
+ import { generateStandardId } from '@logto/shared';
3
3
  import { assert } from '@silverhand/essentials';
4
4
  import { sql } from 'slonik';
5
5
  import { raw } from 'slonik-sql-tag-raw';