@logto/cli 1.0.0-beta.16 → 1.0.0-beta.19

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 (43) hide show
  1. package/bin/logto.js +2 -0
  2. package/lib/commands/connector/add.js +8 -10
  3. package/lib/commands/connector/index.js +9 -14
  4. package/lib/commands/connector/list.js +10 -16
  5. package/lib/commands/connector/remove.js +13 -18
  6. package/lib/commands/connector/utils.d.ts +1 -1
  7. package/lib/commands/connector/utils.js +100 -86
  8. package/lib/commands/database/alteration/index.d.ts +1 -2
  9. package/lib/commands/database/alteration/index.js +36 -98
  10. package/lib/commands/database/alteration/index.test.js +36 -57
  11. package/lib/commands/database/alteration/meta-url.d.ts +1 -0
  12. package/lib/commands/database/alteration/meta-url.js +4 -0
  13. package/lib/commands/database/alteration/type.d.ts +1 -1
  14. package/lib/commands/database/alteration/type.js +1 -2
  15. package/lib/commands/database/alteration/utils.d.ts +4 -0
  16. package/lib/commands/database/alteration/utils.js +39 -0
  17. package/lib/commands/database/alteration/version.d.ts +1 -1
  18. package/lib/commands/database/alteration/version.js +18 -25
  19. package/lib/commands/database/config.js +44 -49
  20. package/lib/commands/database/index.js +7 -12
  21. package/lib/commands/database/seed/index.d.ts +1 -1
  22. package/lib/commands/database/seed/index.js +59 -55
  23. package/lib/commands/database/seed/oidc-config.js +15 -18
  24. package/lib/commands/database/utilities.js +6 -11
  25. package/lib/commands/install/index.d.ts +1 -1
  26. package/lib/commands/install/index.js +14 -28
  27. package/lib/commands/install/utils.d.ts +0 -1
  28. package/lib/commands/install/utils.js +59 -106
  29. package/lib/constants.js +1 -4
  30. package/lib/database.js +33 -43
  31. package/lib/index.js +18 -23
  32. package/lib/meta-url.d.ts +1 -0
  33. package/lib/meta-url.js +4 -0
  34. package/lib/package-json.d.ts +7 -3
  35. package/lib/package-json.js +28 -27
  36. package/lib/queries/logto-config.js +18 -26
  37. package/lib/queries/logto-config.test.js +29 -30
  38. package/lib/test-utilities.d.ts +2 -2
  39. package/lib/test-utilities.js +1 -5
  40. package/lib/utilities.d.ts +5 -5
  41. package/lib/utilities.js +49 -64
  42. package/package.json +27 -23
  43. package/bin/logto +0 -2
package/lib/database.js CHANGED
@@ -1,75 +1,65 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.insertInto = exports.createPoolAndDatabaseIfNeeded = exports.createPoolFromConfig = exports.getDatabaseUrlFromConfig = exports.defaultDatabaseUrl = void 0;
7
- const shared_1 = require("@logto/shared");
8
- const essentials_1 = require("@silverhand/essentials");
9
- const decamelize_1 = __importDefault(require("decamelize"));
10
- const slonik_1 = require("slonik");
11
- const slonik_interceptor_preset_1 = require("slonik-interceptor-preset");
12
- const zod_1 = require("zod");
13
- const utilities_1 = require("./utilities");
14
- exports.defaultDatabaseUrl = 'postgresql://localhost:5432/logto';
15
- const getDatabaseUrlFromConfig = async () => (await (0, utilities_1.getCliConfigWithPrompt)({
16
- key: utilities_1.ConfigKey.DatabaseUrl,
1
+ import { convertToPrimitiveOrSql } from '@logto/shared';
2
+ import { assert } from '@silverhand/essentials';
3
+ import decamelize from 'decamelize';
4
+ import { createPool, parseDsn, sql, stringifyDsn } from 'slonik';
5
+ import { createInterceptors } from 'slonik-interceptor-preset';
6
+ import { z } from 'zod';
7
+ import { ConfigKey, getCliConfigWithPrompt, log } from './utilities.js';
8
+ export const defaultDatabaseUrl = 'postgresql://localhost:5432/logto';
9
+ export const getDatabaseUrlFromConfig = async () => (await getCliConfigWithPrompt({
10
+ key: ConfigKey.DatabaseUrl,
17
11
  readableKey: 'Logto database URL',
18
- defaultValue: exports.defaultDatabaseUrl,
12
+ defaultValue: defaultDatabaseUrl,
19
13
  })) ?? '';
20
- exports.getDatabaseUrlFromConfig = getDatabaseUrlFromConfig;
21
- const createPoolFromConfig = async () => {
22
- const databaseUrl = await (0, exports.getDatabaseUrlFromConfig)();
23
- (0, essentials_1.assert)((0, slonik_1.parseDsn)(databaseUrl).databaseName, new Error('Database name is required in URL'));
24
- return (0, slonik_1.createPool)(databaseUrl, {
25
- interceptors: (0, slonik_interceptor_preset_1.createInterceptors)(),
14
+ export const createPoolFromConfig = async () => {
15
+ const databaseUrl = await getDatabaseUrlFromConfig();
16
+ assert(parseDsn(databaseUrl).databaseName, new Error('Database name is required in URL'));
17
+ return createPool(databaseUrl, {
18
+ interceptors: createInterceptors(),
26
19
  });
27
20
  };
28
- exports.createPoolFromConfig = createPoolFromConfig;
29
21
  /**
30
22
  * Create a database pool with the URL in CLI config; if no URL found, prompt to input.
31
23
  * If the given database does not exists, it will try to create a new database by connecting to the maintenance database `postgres`.
32
24
  *
33
25
  * @returns A new database pool with the database URL in config.
34
26
  */
35
- const createPoolAndDatabaseIfNeeded = async () => {
27
+ export const createPoolAndDatabaseIfNeeded = async () => {
36
28
  try {
37
- return await (0, exports.createPoolFromConfig)();
29
+ return await createPoolFromConfig();
38
30
  }
39
31
  catch (error) {
40
- const result = zod_1.z.object({ code: zod_1.z.string() }).safeParse(error);
32
+ const result = z.object({ code: z.string() }).safeParse(error);
41
33
  // Database does not exist, try to create one
42
34
  // https://www.postgresql.org/docs/14/errcodes-appendix.html
43
35
  if (!(result.success && result.data.code === '3D000')) {
44
- utilities_1.log.error(error);
36
+ log.error(error);
45
37
  }
46
- const databaseUrl = await (0, exports.getDatabaseUrlFromConfig)();
47
- const dsn = (0, slonik_1.parseDsn)(databaseUrl);
38
+ const databaseUrl = await getDatabaseUrlFromConfig();
39
+ const dsn = parseDsn(databaseUrl);
48
40
  // It's ok to fall back to '?' since:
49
41
  // - Database name is required to connect in the previous pool
50
42
  // - It will throw error when creating database using '?'
51
43
  const databaseName = dsn.databaseName ?? '?';
52
- const maintenancePool = await (0, slonik_1.createPool)((0, slonik_1.stringifyDsn)({ ...dsn, databaseName: 'postgres' }), {
53
- interceptors: (0, slonik_interceptor_preset_1.createInterceptors)(),
44
+ const maintenancePool = await createPool(stringifyDsn({ ...dsn, databaseName: 'postgres' }), {
45
+ interceptors: createInterceptors(),
54
46
  });
55
- await maintenancePool.query((0, slonik_1.sql) `
56
- create database ${slonik_1.sql.identifier([databaseName])}
47
+ await maintenancePool.query(sql `
48
+ create database ${sql.identifier([databaseName])}
57
49
  with
58
50
  encoding = 'UTF8'
59
51
  connection_limit = -1;
60
52
  `);
61
53
  await maintenancePool.end();
62
- utilities_1.log.succeed(`Created database ${databaseName}`);
63
- return (0, exports.createPoolFromConfig)();
54
+ log.succeed(`Created database ${databaseName}`);
55
+ return createPoolFromConfig();
64
56
  }
65
57
  };
66
- exports.createPoolAndDatabaseIfNeeded = createPoolAndDatabaseIfNeeded;
67
- const insertInto = (object, table) => {
58
+ export const insertInto = (object, table) => {
68
59
  const keys = Object.keys(object);
69
- return (0, slonik_1.sql) `
70
- insert into ${slonik_1.sql.identifier([table])}
71
- (${slonik_1.sql.join(keys.map((key) => slonik_1.sql.identifier([(0, decamelize_1.default)(key)])), (0, slonik_1.sql) `, `)})
72
- values (${slonik_1.sql.join(keys.map((key) => (0, shared_1.convertToPrimitiveOrSql)(key, object[key] ?? null)), (0, slonik_1.sql) `, `)})
60
+ return sql `
61
+ insert into ${sql.identifier([table])}
62
+ (${sql.join(keys.map((key) => sql.identifier([decamelize(key)])), sql `, `)})
63
+ values (${sql.join(keys.map((key) => convertToPrimitiveOrSql(key, object[key] ?? null)), sql `, `)})
73
64
  `;
74
65
  };
75
- exports.insertInto = insertInto;
package/lib/index.js CHANGED
@@ -1,18 +1,13 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const chalk_1 = __importDefault(require("chalk"));
7
- const dotenv_1 = __importDefault(require("dotenv"));
8
- const yargs_1 = __importDefault(require("yargs"));
9
- const helpers_1 = require("yargs/helpers");
10
- const connector_1 = __importDefault(require("./commands/connector"));
11
- const database_1 = __importDefault(require("./commands/database"));
12
- const install_1 = __importDefault(require("./commands/install"));
13
- const package_json_1 = require("./package-json");
14
- const utilities_1 = require("./utilities");
15
- void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
1
+ import chalk from 'chalk';
2
+ import dotenv from 'dotenv';
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import connector from './commands/connector/index.js';
6
+ import database from './commands/database/index.js';
7
+ import install from './commands/install/index.js';
8
+ import { packageJson } from './package-json.js';
9
+ import { cliConfig, ConfigKey } from './utilities.js';
10
+ void yargs(hideBin(process.argv))
16
11
  .version(false)
17
12
  .option('env', {
18
13
  alias: ['e', 'env-file'],
@@ -32,23 +27,23 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
32
27
  })
33
28
  .middleware(({ version }) => {
34
29
  if (version) {
35
- console.log(package_json_1.packageJson.name + ' v' + package_json_1.packageJson.version);
30
+ console.log(packageJson.name + ' v' + packageJson.version);
36
31
  // eslint-disable-next-line unicorn/no-process-exit
37
32
  process.exit(0);
38
33
  }
39
34
  }, true)
40
35
  .middleware(({ env, db: databaseUrl }) => {
41
- dotenv_1.default.config({ path: env });
42
- const initialDatabaseUrl = databaseUrl ?? process.env[utilities_1.ConfigKey.DatabaseUrl];
36
+ dotenv.config({ path: env });
37
+ const initialDatabaseUrl = databaseUrl ?? process.env[ConfigKey.DatabaseUrl];
43
38
  if (initialDatabaseUrl) {
44
- utilities_1.cliConfig.set(utilities_1.ConfigKey.DatabaseUrl, initialDatabaseUrl);
39
+ cliConfig.set(ConfigKey.DatabaseUrl, initialDatabaseUrl);
45
40
  }
46
41
  })
47
- .command(install_1.default)
48
- .command(database_1.default)
49
- .command(connector_1.default)
42
+ .command(install)
43
+ .command(database)
44
+ .command(connector)
50
45
  .demandCommand(1)
51
- .showHelpOnFail(false, `Specify ${chalk_1.default.green('--help')} for available options`)
46
+ .showHelpOnFail(false, `Specify ${chalk.green('--help')} for available options`)
52
47
  .strict()
53
48
  .parserConfiguration({
54
49
  'dot-notation': false,
@@ -0,0 +1 @@
1
+ export declare const metaUrl: string;
@@ -0,0 +1,4 @@
1
+ // Have to define this in a separate file since Jest sticks with CJS
2
+ // We need to mock this before running tests
3
+ // https://github.com/facebook/jest/issues/12952
4
+ export const metaUrl = import.meta.url;
@@ -5,6 +5,7 @@ export declare const packageJson: {
5
5
  author: string;
6
6
  homepage: string;
7
7
  license: string;
8
+ type: string;
8
9
  publishConfig: {
9
10
  access: string;
10
11
  };
@@ -21,11 +22,13 @@ export declare const packageJson: {
21
22
  precommit: string;
22
23
  "prepare:package-json": string;
23
24
  build: string;
25
+ "build:test": string;
24
26
  dev: string;
25
27
  start: string;
26
28
  "start:dev": string;
27
29
  lint: string;
28
30
  "lint:report": string;
31
+ "test:only": string;
29
32
  test: string;
30
33
  "test:ci": string;
31
34
  prepack: string;
@@ -37,18 +40,19 @@ export declare const packageJson: {
37
40
  url: string;
38
41
  };
39
42
  dependencies: {
43
+ "@logto/core-kit": string;
40
44
  "@logto/schemas": string;
41
45
  "@logto/shared": string;
42
46
  "@silverhand/essentials": string;
43
47
  chalk: string;
44
48
  decamelize: string;
45
49
  dotenv: string;
46
- "fs-extra": string;
47
50
  got: string;
48
51
  hpagent: string;
49
52
  inquirer: string;
50
53
  nanoid: string;
51
54
  ora: string;
55
+ "p-limit": string;
52
56
  "p-retry": string;
53
57
  roarr: string;
54
58
  semver: string;
@@ -61,13 +65,13 @@ export declare const packageJson: {
61
65
  };
62
66
  devDependencies: {
63
67
  "@silverhand/eslint-config": string;
64
- "@silverhand/jest-config": string;
65
68
  "@silverhand/ts-config": string;
66
69
  "@types/fs-extra": string;
67
70
  "@types/inquirer": string;
68
71
  "@types/jest": string;
69
72
  "@types/node": string;
70
73
  "@types/semver": string;
74
+ "@types/sinon": string;
71
75
  "@types/tar": string;
72
76
  "@types/yargs": string;
73
77
  eslint: string;
@@ -75,7 +79,7 @@ export declare const packageJson: {
75
79
  "lint-staged": string;
76
80
  prettier: string;
77
81
  rimraf: string;
78
- "ts-node": string;
82
+ sinon: string;
79
83
  typescript: string;
80
84
  };
81
85
  eslintConfig: {
@@ -1,19 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.packageJson = void 0;
4
- exports.packageJson = {
1
+ export const packageJson = {
5
2
  "name": "@logto/cli",
6
- "version": "1.0.0-beta.16",
3
+ "version": "1.0.0-beta.19",
7
4
  "description": "Logto CLI.",
8
5
  "author": "Silverhand Inc. <contact@silverhand.io>",
9
6
  "homepage": "https://github.com/logto-io/logto#readme",
10
7
  "license": "MPL-2.0",
8
+ "type": "module",
11
9
  "publishConfig": {
12
10
  "access": "public"
13
11
  },
14
12
  "main": "lib/index.js",
15
13
  "bin": {
16
- "logto": "bin/logto"
14
+ "logto": "bin/logto.js"
17
15
  },
18
16
  "files": [
19
17
  "bin",
@@ -27,13 +25,15 @@ exports.packageJson = {
27
25
  "precommit": "lint-staged",
28
26
  "prepare:package-json": "node -p \"'export const packageJson = ' + JSON.stringify(require('./package.json'), undefined, 2) + ';'\" > src/package-json.ts",
29
27
  "build": "rimraf lib && pnpm prepare:package-json && tsc -p tsconfig.build.json",
28
+ "build:test": "rimraf lib/ && pnpm prepare:package-json && tsc -p tsconfig.test.json --sourcemap",
30
29
  "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
31
30
  "start": "node .",
32
- "start:dev": "ts-node --files src/index.ts",
31
+ "start:dev": "pnpm build && node .",
33
32
  "lint": "eslint --ext .ts src",
34
33
  "lint:report": "pnpm lint --format json --output-file report.json",
35
- "test": "jest",
36
- "test:ci": "jest",
34
+ "test:only": "NODE_OPTIONS=--experimental-vm-modules jest",
35
+ "test": "pnpm build:test && pnpm test:only",
36
+ "test:ci": "pnpm test:only",
37
37
  "prepack": "pnpm build"
38
38
  },
39
39
  "engines": {
@@ -43,46 +43,47 @@ exports.packageJson = {
43
43
  "url": "https://github.com/logto-io/logto/issues"
44
44
  },
45
45
  "dependencies": {
46
- "@logto/schemas": "workspace:^",
47
- "@logto/shared": "workspace:^",
48
- "@silverhand/essentials": "^1.3.0",
49
- "chalk": "^4.1.2",
50
- "decamelize": "^5.0.0",
46
+ "@logto/core-kit": "workspace:*",
47
+ "@logto/schemas": "workspace:*",
48
+ "@logto/shared": "workspace:*",
49
+ "@silverhand/essentials": "2.1.0",
50
+ "chalk": "^5.0.0",
51
+ "decamelize": "^6.0.0",
51
52
  "dotenv": "^16.0.0",
52
- "fs-extra": "^10.1.0",
53
- "got": "^11.8.5",
54
- "hpagent": "^1.0.0",
53
+ "got": "^12.5.3",
54
+ "hpagent": "^1.2.0",
55
55
  "inquirer": "^8.2.2",
56
- "nanoid": "^3.3.4",
57
- "ora": "^5.0.0",
58
- "p-retry": "^4.6.1",
56
+ "nanoid": "^4.0.0",
57
+ "ora": "^6.1.2",
58
+ "p-limit": "^4.0.0",
59
+ "p-retry": "^5.1.2",
59
60
  "roarr": "^7.11.0",
60
- "semver": "^7.3.7",
61
+ "semver": "^7.3.8",
61
62
  "slonik": "^30.0.0",
62
63
  "slonik-interceptor-preset": "^1.2.10",
63
64
  "slonik-sql-tag-raw": "^1.1.4",
64
65
  "tar": "^6.1.11",
65
66
  "yargs": "^17.6.0",
66
- "zod": "^3.19.1"
67
+ "zod": "^3.20.2"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@silverhand/eslint-config": "1.3.0",
70
- "@silverhand/jest-config": "1.2.2",
71
71
  "@silverhand/ts-config": "1.2.1",
72
72
  "@types/fs-extra": "^9.0.13",
73
73
  "@types/inquirer": "^8.2.1",
74
74
  "@types/jest": "^29.1.2",
75
75
  "@types/node": "^16.0.0",
76
76
  "@types/semver": "^7.3.12",
77
+ "@types/sinon": "^10.0.13",
77
78
  "@types/tar": "^6.1.2",
78
79
  "@types/yargs": "^17.0.13",
79
80
  "eslint": "^8.21.0",
80
- "jest": "^29.1.2",
81
+ "jest": "^29.3.1",
81
82
  "lint-staged": "^13.0.0",
82
- "prettier": "^2.7.1",
83
+ "prettier": "^2.8.1",
83
84
  "rimraf": "^3.0.2",
84
- "ts-node": "^10.9.1",
85
- "typescript": "^4.7.4"
85
+ "sinon": "^15.0.0",
86
+ "typescript": "^4.9.4"
86
87
  },
87
88
  "eslintConfig": {
88
89
  "extends": "@silverhand",
@@ -1,35 +1,29 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateDatabaseTimestamp = exports.getCurrentDatabaseAlterationTimestamp = exports.updateValueByKey = exports.getRowsByKeys = exports.doesConfigsTableExist = void 0;
4
- const schemas_1 = require("@logto/schemas");
5
- const shared_1 = require("@logto/shared");
6
- const slonik_1 = require("slonik");
7
- const zod_1 = require("zod");
8
- const { table, fields } = (0, shared_1.convertToIdentifiers)(schemas_1.LogtoConfigs);
9
- const doesConfigsTableExist = async (pool) => {
10
- const { rows } = await pool.query((0, slonik_1.sql) `select to_regclass(${schemas_1.LogtoConfigs.table}) as regclass`);
1
+ import { logtoConfigGuards, LogtoConfigs, AlterationStateKey } from '@logto/schemas';
2
+ import { convertToIdentifiers } from '@logto/shared';
3
+ import { sql } from 'slonik';
4
+ import { z } from 'zod';
5
+ const { table, fields } = convertToIdentifiers(LogtoConfigs);
6
+ export const doesConfigsTableExist = async (pool) => {
7
+ const { rows } = await pool.query(sql `select to_regclass(${LogtoConfigs.table}) as regclass`);
11
8
  return Boolean(rows[0]?.regclass);
12
9
  };
13
- exports.doesConfigsTableExist = doesConfigsTableExist;
14
- const getRowsByKeys = async (pool, keys) => pool.query((0, slonik_1.sql) `
15
- select ${slonik_1.sql.join([fields.key, fields.value], (0, slonik_1.sql) `,`)} from ${table}
16
- where ${fields.key} in (${slonik_1.sql.join(keys, (0, slonik_1.sql) `,`)})
10
+ export const getRowsByKeys = async (pool, keys) => pool.query(sql `
11
+ select ${sql.join([fields.key, fields.value], sql `,`)} from ${table}
12
+ where ${fields.key} in (${sql.join(keys, sql `,`)})
17
13
  `);
18
- exports.getRowsByKeys = getRowsByKeys;
19
- const updateValueByKey = async (pool, key, value) => pool.query((0, slonik_1.sql) `
14
+ export const updateValueByKey = async (pool, key, value) => pool.query(sql `
20
15
  insert into ${table} (${fields.key}, ${fields.value})
21
- values (${key}, ${slonik_1.sql.jsonb(value)})
16
+ values (${key}, ${sql.jsonb(value)})
22
17
  on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
23
18
  `);
24
- exports.updateValueByKey = updateValueByKey;
25
- const getCurrentDatabaseAlterationTimestamp = async (pool) => {
19
+ export const getCurrentDatabaseAlterationTimestamp = async (pool) => {
26
20
  try {
27
- const result = await pool.maybeOne((0, slonik_1.sql) `select * from ${table} where ${fields.key}=${schemas_1.AlterationStateKey.AlterationState}`);
28
- const parsed = schemas_1.logtoConfigGuards[schemas_1.AlterationStateKey.AlterationState].safeParse(result?.value);
21
+ const result = await pool.maybeOne(sql `select * from ${table} where ${fields.key}=${AlterationStateKey.AlterationState}`);
22
+ const parsed = logtoConfigGuards[AlterationStateKey.AlterationState].safeParse(result?.value);
29
23
  return (parsed.success && parsed.data.timestamp) || 0;
30
24
  }
31
25
  catch (error) {
32
- const result = zod_1.z.object({ code: zod_1.z.string() }).safeParse(error);
26
+ const result = z.object({ code: z.string() }).safeParse(error);
33
27
  // Relation does not exist, treat as 0
34
28
  // https://www.postgresql.org/docs/14/errcodes-appendix.html
35
29
  if (result.success && result.data.code === '42P01') {
@@ -38,12 +32,10 @@ const getCurrentDatabaseAlterationTimestamp = async (pool) => {
38
32
  throw error;
39
33
  }
40
34
  };
41
- exports.getCurrentDatabaseAlterationTimestamp = getCurrentDatabaseAlterationTimestamp;
42
- const updateDatabaseTimestamp = async (connection, timestamp) => {
35
+ export const updateDatabaseTimestamp = async (connection, timestamp) => {
43
36
  const value = {
44
37
  timestamp,
45
38
  updatedAt: new Date().toISOString(),
46
39
  };
47
- return (0, exports.updateValueByKey)(connection, schemas_1.AlterationStateKey.AlterationState, value);
40
+ return updateValueByKey(connection, AlterationStateKey.AlterationState, value);
48
41
  };
49
- exports.updateDatabaseTimestamp = updateDatabaseTimestamp;
@@ -1,60 +1,59 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const schemas_1 = require("@logto/schemas");
4
- const shared_1 = require("@logto/shared");
5
- const slonik_1 = require("slonik");
6
- const test_utilities_1 = require("../test-utilities");
7
- const logto_config_1 = require("./logto-config");
1
+ import { AlterationStateKey, LogtoConfigs } from '@logto/schemas';
2
+ import { convertToIdentifiers } from '@logto/shared';
3
+ import { createMockPool, createMockQueryResult, sql } from 'slonik';
4
+ import { expectSqlAssert } from '../test-utilities.js';
5
+ import { updateDatabaseTimestamp, getCurrentDatabaseAlterationTimestamp } from './logto-config.js';
6
+ const { jest } = import.meta;
8
7
  const mockQuery = jest.fn();
9
- const pool = (0, slonik_1.createMockPool)({
8
+ const pool = createMockPool({
10
9
  query: async (sql, values) => {
11
10
  return mockQuery(sql, values);
12
11
  },
13
12
  });
14
- const { table, fields } = (0, shared_1.convertToIdentifiers)(schemas_1.LogtoConfigs);
13
+ const { table, fields } = convertToIdentifiers(LogtoConfigs);
15
14
  const timestamp = 1663923776;
16
15
  describe('getCurrentDatabaseAlterationTimestamp()', () => {
17
16
  it('returns 0 if query failed (table not found)', async () => {
18
17
  mockQuery.mockRejectedValueOnce({ code: '42P01' });
19
- await expect((0, logto_config_1.getCurrentDatabaseAlterationTimestamp)(pool)).resolves.toBe(0);
18
+ await expect(getCurrentDatabaseAlterationTimestamp(pool)).resolves.toBe(0);
20
19
  });
21
20
  it('returns 0 if the row is not found', async () => {
22
- const expectSql = (0, slonik_1.sql) `
21
+ const expectSql = sql `
23
22
  select * from ${table} where ${fields.key}=$1
24
23
  `;
25
24
  mockQuery.mockImplementationOnce(async (sql, values) => {
26
- (0, test_utilities_1.expectSqlAssert)(sql, expectSql.sql);
27
- expect(values).toEqual([schemas_1.AlterationStateKey.AlterationState]);
28
- return (0, slonik_1.createMockQueryResult)([]);
25
+ expectSqlAssert(sql, expectSql.sql);
26
+ expect(values).toEqual([AlterationStateKey.AlterationState]);
27
+ return createMockQueryResult([]);
29
28
  });
30
- await expect((0, logto_config_1.getCurrentDatabaseAlterationTimestamp)(pool)).resolves.toBe(0);
29
+ await expect(getCurrentDatabaseAlterationTimestamp(pool)).resolves.toBe(0);
31
30
  });
32
31
  it('returns 0 if the value is in bad format', async () => {
33
- const expectSql = (0, slonik_1.sql) `
32
+ const expectSql = sql `
34
33
  select * from ${table} where ${fields.key}=$1
35
34
  `;
36
35
  mockQuery.mockImplementationOnce(async (sql, values) => {
37
- (0, test_utilities_1.expectSqlAssert)(sql, expectSql.sql);
38
- expect(values).toEqual([schemas_1.AlterationStateKey.AlterationState]);
39
- return (0, slonik_1.createMockQueryResult)([{ value: 'some_value' }]);
36
+ expectSqlAssert(sql, expectSql.sql);
37
+ expect(values).toEqual([AlterationStateKey.AlterationState]);
38
+ return createMockQueryResult([{ value: 'some_value' }]);
40
39
  });
41
- await expect((0, logto_config_1.getCurrentDatabaseAlterationTimestamp)(pool)).resolves.toBe(0);
40
+ await expect(getCurrentDatabaseAlterationTimestamp(pool)).resolves.toBe(0);
42
41
  });
43
42
  it('returns the timestamp from database', async () => {
44
- const expectSql = (0, slonik_1.sql) `
43
+ const expectSql = sql `
45
44
  select * from ${table} where ${fields.key}=$1
46
45
  `;
47
46
  mockQuery.mockImplementationOnce(async (sql, values) => {
48
- (0, test_utilities_1.expectSqlAssert)(sql, expectSql.sql);
49
- expect(values).toEqual([schemas_1.AlterationStateKey.AlterationState]);
47
+ expectSqlAssert(sql, expectSql.sql);
48
+ expect(values).toEqual([AlterationStateKey.AlterationState]);
50
49
  // @ts-expect-error createMockQueryResult doesn't support jsonb
51
- return (0, slonik_1.createMockQueryResult)([{ value: { timestamp, updatedAt: 'now' } }]);
50
+ return createMockQueryResult([{ value: { timestamp, updatedAt: 'now' } }]);
52
51
  });
53
- await expect((0, logto_config_1.getCurrentDatabaseAlterationTimestamp)(pool)).resolves.toEqual(timestamp);
52
+ await expect(getCurrentDatabaseAlterationTimestamp(pool)).resolves.toEqual(timestamp);
54
53
  });
55
54
  });
56
55
  describe('updateDatabaseTimestamp()', () => {
57
- const expectSql = (0, slonik_1.sql) `
56
+ const expectSql = sql `
58
57
  insert into ${table} (${fields.key}, ${fields.value})
59
58
  values ($1, $2::jsonb)
60
59
  on conflict (${fields.key}) do update set ${fields.value}=excluded.${fields.value}
@@ -69,13 +68,13 @@ describe('updateDatabaseTimestamp()', () => {
69
68
  });
70
69
  it('sends upsert sql with timestamp and updatedAt', async () => {
71
70
  mockQuery.mockImplementationOnce(async (sql, values) => {
72
- (0, test_utilities_1.expectSqlAssert)(sql, expectSql.sql);
71
+ expectSqlAssert(sql, expectSql.sql);
73
72
  expect(values).toEqual([
74
- schemas_1.AlterationStateKey.AlterationState,
73
+ AlterationStateKey.AlterationState,
75
74
  JSON.stringify({ timestamp, updatedAt }),
76
75
  ]);
77
- return (0, slonik_1.createMockQueryResult)([]);
76
+ return createMockQueryResult([]);
78
77
  });
79
- await (0, logto_config_1.updateDatabaseTimestamp)(pool, timestamp);
78
+ await updateDatabaseTimestamp(pool, timestamp);
80
79
  });
81
80
  });
@@ -1,6 +1,6 @@
1
1
  import type { QueryResult, QueryResultRow } from 'slonik';
2
- import type { PrimitiveValueExpression } from 'slonik/dist/src/types.d';
3
- export declare type QueryType = (sql: string, values: readonly PrimitiveValueExpression[]) => Promise<QueryResult<QueryResultRow>>;
2
+ import type { PrimitiveValueExpression } from 'slonik/dist/src/types.js';
3
+ export type QueryType = (sql: string, values: readonly PrimitiveValueExpression[]) => Promise<QueryResult<QueryResultRow>>;
4
4
  /**
5
5
  * Slonik Query Mock Utils
6
6
  **/
@@ -1,11 +1,8 @@
1
- "use strict";
2
1
  // Copied from core
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.expectSqlAssert = void 0;
5
2
  /**
6
3
  * Slonik Query Mock Utils
7
4
  **/
8
- const expectSqlAssert = (sql, expectSql) => {
5
+ export const expectSqlAssert = (sql, expectSql) => {
9
6
  expect(sql
10
7
  .split('\n')
11
8
  .map((row) => row.trim())
@@ -14,4 +11,3 @@ const expectSqlAssert = (sql, expectSql) => {
14
11
  .map((row) => row.trim())
15
12
  .filter(Boolean));
16
13
  };
17
- exports.expectSqlAssert = expectSqlAssert;
@@ -1,7 +1,7 @@
1
1
  import type { Optional } from '@silverhand/essentials';
2
- import ora from 'ora';
2
+ import type { Options } from 'ora';
3
3
  export declare const safeExecSync: (command: string) => string | undefined;
4
- declare type Log = Readonly<{
4
+ type Log = Readonly<{
5
5
  info: typeof console.log;
6
6
  succeed: typeof console.log;
7
7
  warn: typeof console.log;
@@ -10,13 +10,13 @@ declare type Log = Readonly<{
10
10
  export declare const log: Log;
11
11
  export declare const downloadFile: (url: string, destination: string) => Promise<unknown>;
12
12
  export declare const getPathInModule: (moduleName: string, relativePath?: string) => string;
13
- export declare const oraPromise: <T>(promise: PromiseLike<T>, options?: ora.Options, exitOnError?: boolean) => Promise<T>;
13
+ export declare const oraPromise: <T>(promise: PromiseLike<T>, options?: Options, exitOnError?: boolean) => Promise<T>;
14
14
  export declare const isTty: () => boolean;
15
15
  export declare enum ConfigKey {
16
16
  DatabaseUrl = "DB_URL"
17
17
  }
18
18
  export declare const cliConfig: Map<ConfigKey, Optional<string>>;
19
- export declare type GetCliConfigWithPrompt = {
19
+ export type GetCliConfigWithPrompt = {
20
20
  key: ConfigKey;
21
21
  readableKey: string;
22
22
  comments?: string;
@@ -32,7 +32,7 @@ export declare const getCliConfigWithPrompt: ({ key, readableKey, comments, defa
32
32
  * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
33
33
  */
34
34
  export declare function findLastIndex<T>(array: readonly T[], predicate: (value: T, index: number, object: readonly T[]) => boolean): number;
35
- export declare type ConnectorPackage = {
35
+ export type ConnectorPackage = {
36
36
  name: string;
37
37
  path: string;
38
38
  };