@constructive-io/cli 5.1.24 → 5.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.
- package/README.md +98 -539
- package/commands.js +4 -11
- package/esm/commands.js +3 -10
- package/esm/utils/argv.js +8 -0
- package/esm/utils/cli-error.js +31 -0
- package/esm/utils/display.js +13 -43
- package/esm/utils/index.js +2 -2
- package/esm/utils/update-check.js +107 -0
- package/package.json +11 -11
- package/utils/argv.d.ts +8 -0
- package/utils/argv.js +12 -0
- package/utils/cli-error.d.ts +6 -0
- package/utils/cli-error.js +35 -0
- package/utils/display.d.ts +1 -1
- package/utils/display.js +13 -43
- package/utils/index.d.ts +2 -2
- package/utils/index.js +4 -4
- package/utils/update-check.d.ts +15 -0
- package/utils/update-check.js +113 -0
package/commands.js
CHANGED
|
@@ -5,16 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.commands = void 0;
|
|
7
7
|
const find_and_require_package_json_1 = require("find-and-require-package-json");
|
|
8
|
-
const pgpm_1 = require("pgpm");
|
|
9
8
|
const codegen_1 = __importDefault(require("./commands/codegen"));
|
|
10
9
|
const explorer_1 = __importDefault(require("./commands/explorer"));
|
|
11
10
|
const get_graphql_schema_1 = __importDefault(require("./commands/get-graphql-schema"));
|
|
12
11
|
const server_1 = __importDefault(require("./commands/server"));
|
|
13
12
|
const utils_1 = require("./utils");
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
const update_check_1 = require("./utils/update-check");
|
|
14
|
+
const createCommandMap = () => {
|
|
16
15
|
return {
|
|
17
|
-
...pgpmCommands,
|
|
18
16
|
server: server_1.default,
|
|
19
17
|
explorer: explorer_1.default,
|
|
20
18
|
'get-graphql-schema': get_graphql_schema_1.default,
|
|
@@ -26,7 +24,7 @@ const commands = async (argv, prompter, options) => {
|
|
|
26
24
|
// Run update check early so it shows on help/version paths too
|
|
27
25
|
try {
|
|
28
26
|
const pkg = (0, find_and_require_package_json_1.findAndRequirePackageJson)(__dirname);
|
|
29
|
-
await (0,
|
|
27
|
+
await (0, update_check_1.checkForUpdates)({
|
|
30
28
|
command: command || 'help',
|
|
31
29
|
pkgName: pkg.name,
|
|
32
30
|
pkgVersion: pkg.version,
|
|
@@ -53,12 +51,7 @@ const commands = async (argv, prompter, options) => {
|
|
|
53
51
|
console.log(utils_1.usageText);
|
|
54
52
|
process.exit(0);
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
if (command === 'init' && (argv.help || argv.h)) {
|
|
58
|
-
console.log((0, pgpm_1.createInitUsageText)('constructive', 'Constructive'));
|
|
59
|
-
process.exit(0);
|
|
60
|
-
}
|
|
61
|
-
const commandMap = createCommandMap(options?.skipPgTeardown);
|
|
54
|
+
const commandMap = createCommandMap();
|
|
62
55
|
// Prompt if no command provided
|
|
63
56
|
if (!command) {
|
|
64
57
|
const answer = await prompter.prompt(argv, [
|
package/esm/commands.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { findAndRequirePackageJson } from 'find-and-require-package-json';
|
|
2
|
-
import { checkForUpdates, createInitUsageText, createPgpmCommandMap } from 'pgpm';
|
|
3
2
|
import codegen from './commands/codegen';
|
|
4
3
|
import explorer from './commands/explorer';
|
|
5
4
|
import getGraphqlSchema from './commands/get-graphql-schema';
|
|
6
5
|
import server from './commands/server';
|
|
7
6
|
import { cliExitWithError, extractFirst, usageText } from './utils';
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import { checkForUpdates } from './utils/update-check';
|
|
8
|
+
const createCommandMap = () => {
|
|
10
9
|
return {
|
|
11
|
-
...pgpmCommands,
|
|
12
10
|
server,
|
|
13
11
|
explorer,
|
|
14
12
|
'get-graphql-schema': getGraphqlSchema,
|
|
@@ -47,12 +45,7 @@ export const commands = async (argv, prompter, options) => {
|
|
|
47
45
|
console.log(usageText);
|
|
48
46
|
process.exit(0);
|
|
49
47
|
}
|
|
50
|
-
|
|
51
|
-
if (command === 'init' && (argv.help || argv.h)) {
|
|
52
|
-
console.log(createInitUsageText('constructive', 'Constructive'));
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}
|
|
55
|
-
const commandMap = createCommandMap(options?.skipPgTeardown);
|
|
48
|
+
const commandMap = createCommandMap();
|
|
56
49
|
// Prompt if no command provided
|
|
57
50
|
if (!command) {
|
|
58
51
|
const answer = await prompter.prompt(argv, [
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Logger } from '@pgpmjs/logger';
|
|
2
|
+
import { PgpmError } from '@pgpmjs/types';
|
|
3
|
+
const log = new Logger('cli');
|
|
4
|
+
/**
|
|
5
|
+
* CLI error utility that logs error information and exits with code 1.
|
|
6
|
+
* Provides consistent error handling and user experience across all CLI commands.
|
|
7
|
+
*/
|
|
8
|
+
export const cliExitWithError = async (error, context) => {
|
|
9
|
+
if (error instanceof PgpmError) {
|
|
10
|
+
log.error(`Error: ${error.message}`);
|
|
11
|
+
if (error.context && Object.keys(error.context).length > 0) {
|
|
12
|
+
log.debug('Error context:', error.context);
|
|
13
|
+
}
|
|
14
|
+
if (context) {
|
|
15
|
+
log.debug('Additional context:', context);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else if (error instanceof Error) {
|
|
19
|
+
log.error(`Error: ${error.message}`);
|
|
20
|
+
if (context) {
|
|
21
|
+
log.debug('Context:', context);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (typeof error === 'string') {
|
|
25
|
+
log.error(`Error: ${error}`);
|
|
26
|
+
if (context) {
|
|
27
|
+
log.debug('Context:', context);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
process.exit(1);
|
|
31
|
+
};
|
package/esm/utils/display.js
CHANGED
|
@@ -2,63 +2,33 @@ export const usageText = `
|
|
|
2
2
|
Usage: cnc <command> [options]
|
|
3
3
|
constructive <command> [options]
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
add Add database changes to plans and create SQL files
|
|
7
|
-
deploy Deploy database changes and migrations
|
|
8
|
-
verify Verify database state and migrations
|
|
9
|
-
revert Revert database changes and migrations
|
|
5
|
+
Constructive CLI - API Server and Development Tools
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
init Initialize pgpm workspace or module
|
|
13
|
-
extension Manage module dependencies
|
|
14
|
-
plan Generate module deployment plans
|
|
15
|
-
package Package module for distribution
|
|
16
|
-
update Update CLI/pgpm (installs pgpm by default)
|
|
17
|
-
cache Manage cached templates (clean)
|
|
18
|
-
upgrade-modules Upgrade installed pgpm modules to latest versions
|
|
19
|
-
|
|
20
|
-
Development Tools:
|
|
7
|
+
GraphQL Server:
|
|
21
8
|
server Start a GraphQL server
|
|
22
9
|
explorer Launch GraphiQL explorer interface
|
|
23
|
-
docker Manage PostgreSQL Docker containers (start/stop)
|
|
24
|
-
export Export database migrations from existing databases
|
|
25
|
-
env Display environment configuration
|
|
26
10
|
|
|
27
11
|
Code Generation:
|
|
28
12
|
codegen Generate TypeScript types and SDK from GraphQL schema
|
|
29
13
|
get-graphql-schema Fetch or build GraphQL schema SDL
|
|
30
14
|
|
|
31
|
-
Database Administration:
|
|
32
|
-
kill Terminate database connections and optionally drop databases
|
|
33
|
-
install Install pgpm modules
|
|
34
|
-
tag Add tags to changes for versioning
|
|
35
|
-
clear Clear database state
|
|
36
|
-
remove Remove database changes
|
|
37
|
-
analyze Analyze database structure
|
|
38
|
-
rename Rename database changes
|
|
39
|
-
admin-users Manage admin users
|
|
40
|
-
|
|
41
|
-
Testing:
|
|
42
|
-
test-packages Run integration tests on all workspace packages
|
|
43
|
-
|
|
44
|
-
Migration Tools:
|
|
45
|
-
migrate Migration management subcommands
|
|
46
|
-
init Initialize migration tracking
|
|
47
|
-
status Show migration status
|
|
48
|
-
list List all changes
|
|
49
|
-
deps Show change dependencies
|
|
50
|
-
|
|
51
15
|
Global Options:
|
|
52
16
|
-h, --help Display this help information
|
|
53
17
|
-v, --version Display version information
|
|
54
18
|
--cwd <directory> Working directory (default: current directory)
|
|
55
19
|
|
|
56
20
|
Individual Command Help:
|
|
57
|
-
|
|
58
|
-
|
|
21
|
+
cnc <command> --help Display detailed help for specific command
|
|
22
|
+
cnc <command> -h Display detailed help for specific command
|
|
59
23
|
|
|
60
24
|
Examples:
|
|
61
|
-
cnc
|
|
62
|
-
cnc server --port 8080
|
|
63
|
-
cnc
|
|
25
|
+
cnc server Start GraphQL server
|
|
26
|
+
cnc server --port 8080 Start server on custom port
|
|
27
|
+
cnc explorer Launch GraphiQL explorer
|
|
28
|
+
cnc codegen --schema schema.graphql Generate types from schema
|
|
29
|
+
cnc get-graphql-schema --out schema.graphql Export schema SDL
|
|
30
|
+
|
|
31
|
+
Database Operations:
|
|
32
|
+
For database migrations, packages, and deployment, use pgpm:
|
|
33
|
+
https://pgpm.io
|
|
64
34
|
`;
|
package/esm/utils/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { extractFirst } from '
|
|
2
|
-
export { cliExitWithError } from '
|
|
1
|
+
export { extractFirst } from './argv';
|
|
2
|
+
export { cliExitWithError } from './cli-error';
|
|
3
3
|
export { usageText } from './display';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { findAndRequirePackageJson } from 'find-and-require-package-json';
|
|
2
|
+
import { Logger } from '@pgpmjs/logger';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
const log = new Logger('update-check');
|
|
7
|
+
const UPDATE_CHECK_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
|
|
8
|
+
const shouldSkip = (command) => {
|
|
9
|
+
if (process.env.PGPM_SKIP_UPDATE_CHECK)
|
|
10
|
+
return true;
|
|
11
|
+
if (process.env.CI === 'true')
|
|
12
|
+
return true;
|
|
13
|
+
return false;
|
|
14
|
+
};
|
|
15
|
+
function getConfigPath(toolName, key) {
|
|
16
|
+
const configDir = path.join(os.homedir(), `.${toolName}`);
|
|
17
|
+
return path.join(configDir, `${key}.json`);
|
|
18
|
+
}
|
|
19
|
+
function readConfig(toolName, key) {
|
|
20
|
+
try {
|
|
21
|
+
const configPath = getConfigPath(toolName, key);
|
|
22
|
+
if (!fs.existsSync(configPath))
|
|
23
|
+
return null;
|
|
24
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
25
|
+
return JSON.parse(content);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function writeConfig(toolName, key, config) {
|
|
32
|
+
try {
|
|
33
|
+
const configPath = getConfigPath(toolName, key);
|
|
34
|
+
const configDir = path.dirname(configPath);
|
|
35
|
+
if (!fs.existsSync(configDir)) {
|
|
36
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Ignore write errors
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function fetchLatestVersion(pkgName) {
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(`https://registry.npmjs.org/${pkgName}/latest`);
|
|
47
|
+
if (!response.ok)
|
|
48
|
+
return null;
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
return data.version || null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function compareVersions(current, latest) {
|
|
57
|
+
const currentParts = current.replace(/^v/, '').split('.').map(Number);
|
|
58
|
+
const latestParts = latest.replace(/^v/, '').split('.').map(Number);
|
|
59
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
60
|
+
const c = currentParts[i] || 0;
|
|
61
|
+
const l = latestParts[i] || 0;
|
|
62
|
+
if (c < l)
|
|
63
|
+
return -1;
|
|
64
|
+
if (c > l)
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
export async function checkForUpdates(options = {}) {
|
|
70
|
+
const { pkgName = '@constructive-io/cli', pkgVersion = findAndRequirePackageJson(__dirname).version, command, now = Date.now(), key = 'update-check', toolName = 'constructive' } = options;
|
|
71
|
+
if (shouldSkip(command)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const existing = readConfig(toolName, key);
|
|
76
|
+
let latestKnownVersion = existing?.latestKnownVersion ?? pkgVersion;
|
|
77
|
+
const needsCheck = !existing?.lastCheckedAt || (now - existing.lastCheckedAt) > UPDATE_CHECK_TTL_MS;
|
|
78
|
+
if (needsCheck) {
|
|
79
|
+
const fetched = await fetchLatestVersion(pkgName);
|
|
80
|
+
if (fetched) {
|
|
81
|
+
latestKnownVersion = fetched;
|
|
82
|
+
}
|
|
83
|
+
writeConfig(toolName, key, {
|
|
84
|
+
lastCheckedAt: now,
|
|
85
|
+
latestKnownVersion
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const comparison = compareVersions(pkgVersion, latestKnownVersion);
|
|
89
|
+
const isOutdated = comparison < 0;
|
|
90
|
+
if (isOutdated) {
|
|
91
|
+
const updateInstruction = options.updateCommand ?? `Run npm i -g ${pkgName}@latest to upgrade.`;
|
|
92
|
+
log.warn(`A new version of ${pkgName} is available (current ${pkgVersion}, latest ${latestKnownVersion}). ${updateInstruction}`);
|
|
93
|
+
writeConfig(toolName, key, {
|
|
94
|
+
lastCheckedAt: now,
|
|
95
|
+
latestKnownVersion
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
lastCheckedAt: now,
|
|
100
|
+
latestKnownVersion
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
log.debug('Update check skipped due to error:', error);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive CLI",
|
|
6
6
|
"main": "index.js",
|
|
@@ -46,21 +46,21 @@
|
|
|
46
46
|
"ts-node": "^10.9.2"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@constructive-io/graphql-codegen": "^2.17.
|
|
50
|
-
"@constructive-io/graphql-env": "^2.8.
|
|
51
|
-
"@constructive-io/graphql-explorer": "^2.10.
|
|
52
|
-
"@constructive-io/graphql-server": "^2.10.
|
|
53
|
-
"@pgpmjs/core": "^4.1.
|
|
49
|
+
"@constructive-io/graphql-codegen": "^2.17.33",
|
|
50
|
+
"@constructive-io/graphql-env": "^2.8.11",
|
|
51
|
+
"@constructive-io/graphql-explorer": "^2.10.26",
|
|
52
|
+
"@constructive-io/graphql-server": "^2.10.26",
|
|
53
|
+
"@pgpmjs/core": "^4.1.2",
|
|
54
54
|
"@pgpmjs/logger": "^1.3.5",
|
|
55
|
-
"@pgpmjs/server-utils": "^2.8.
|
|
56
|
-
"@pgpmjs/types": "^2.12.
|
|
55
|
+
"@pgpmjs/server-utils": "^2.8.11",
|
|
56
|
+
"@pgpmjs/types": "^2.12.8",
|
|
57
57
|
"find-and-require-package-json": "^0.8.2",
|
|
58
58
|
"inquirerer": "^2.4.0",
|
|
59
59
|
"js-yaml": "^4.1.0",
|
|
60
60
|
"minimist": "^1.2.8",
|
|
61
|
-
"pg-cache": "^1.6.
|
|
61
|
+
"pg-cache": "^1.6.11",
|
|
62
62
|
"pg-env": "^1.2.4",
|
|
63
|
-
"pgpm": "^2.
|
|
63
|
+
"pgpm": "^2.3.0",
|
|
64
64
|
"shelljs": "^0.10.0",
|
|
65
65
|
"yanse": "^0.1.8"
|
|
66
66
|
},
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"postgres",
|
|
76
76
|
"graphile"
|
|
77
77
|
],
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "c2e68f9808a87e3231d9b9af5e706bef5dbd2af8"
|
|
79
79
|
}
|
package/utils/argv.d.ts
ADDED
package/utils/argv.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractFirst = void 0;
|
|
4
|
+
const extractFirst = (argv) => {
|
|
5
|
+
const first = argv._?.[0];
|
|
6
|
+
const newArgv = {
|
|
7
|
+
...argv,
|
|
8
|
+
_: argv._?.slice(1) ?? []
|
|
9
|
+
};
|
|
10
|
+
return { first, newArgv };
|
|
11
|
+
};
|
|
12
|
+
exports.extractFirst = extractFirst;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PgpmError } from '@pgpmjs/types';
|
|
2
|
+
/**
|
|
3
|
+
* CLI error utility that logs error information and exits with code 1.
|
|
4
|
+
* Provides consistent error handling and user experience across all CLI commands.
|
|
5
|
+
*/
|
|
6
|
+
export declare const cliExitWithError: (error: PgpmError | Error | string, context?: Record<string, any>) => Promise<never>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cliExitWithError = void 0;
|
|
4
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
5
|
+
const types_1 = require("@pgpmjs/types");
|
|
6
|
+
const log = new logger_1.Logger('cli');
|
|
7
|
+
/**
|
|
8
|
+
* CLI error utility that logs error information and exits with code 1.
|
|
9
|
+
* Provides consistent error handling and user experience across all CLI commands.
|
|
10
|
+
*/
|
|
11
|
+
const cliExitWithError = async (error, context) => {
|
|
12
|
+
if (error instanceof types_1.PgpmError) {
|
|
13
|
+
log.error(`Error: ${error.message}`);
|
|
14
|
+
if (error.context && Object.keys(error.context).length > 0) {
|
|
15
|
+
log.debug('Error context:', error.context);
|
|
16
|
+
}
|
|
17
|
+
if (context) {
|
|
18
|
+
log.debug('Additional context:', context);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (error instanceof Error) {
|
|
22
|
+
log.error(`Error: ${error.message}`);
|
|
23
|
+
if (context) {
|
|
24
|
+
log.debug('Context:', context);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if (typeof error === 'string') {
|
|
28
|
+
log.error(`Error: ${error}`);
|
|
29
|
+
if (context) {
|
|
30
|
+
log.debug('Context:', context);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
process.exit(1);
|
|
34
|
+
};
|
|
35
|
+
exports.cliExitWithError = cliExitWithError;
|
package/utils/display.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const usageText = "\n Usage: cnc <command> [options]\n constructive <command> [options]\n\n
|
|
1
|
+
export declare const usageText = "\n Usage: cnc <command> [options]\n constructive <command> [options]\n\n Constructive CLI - API Server and Development Tools\n\n GraphQL Server:\n server Start a GraphQL server\n explorer Launch GraphiQL explorer interface\n\n Code Generation:\n codegen Generate TypeScript types and SDK from GraphQL schema\n get-graphql-schema Fetch or build GraphQL schema SDL\n\n Global Options:\n -h, --help Display this help information\n -v, --version Display version information\n --cwd <directory> Working directory (default: current directory)\n\n Individual Command Help:\n cnc <command> --help Display detailed help for specific command\n cnc <command> -h Display detailed help for specific command\n\n Examples:\n cnc server Start GraphQL server\n cnc server --port 8080 Start server on custom port\n cnc explorer Launch GraphiQL explorer\n cnc codegen --schema schema.graphql Generate types from schema\n cnc get-graphql-schema --out schema.graphql Export schema SDL\n\n Database Operations:\n For database migrations, packages, and deployment, use pgpm:\n https://pgpm.io\n ";
|
package/utils/display.js
CHANGED
|
@@ -5,63 +5,33 @@ exports.usageText = `
|
|
|
5
5
|
Usage: cnc <command> [options]
|
|
6
6
|
constructive <command> [options]
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
add Add database changes to plans and create SQL files
|
|
10
|
-
deploy Deploy database changes and migrations
|
|
11
|
-
verify Verify database state and migrations
|
|
12
|
-
revert Revert database changes and migrations
|
|
8
|
+
Constructive CLI - API Server and Development Tools
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
init Initialize pgpm workspace or module
|
|
16
|
-
extension Manage module dependencies
|
|
17
|
-
plan Generate module deployment plans
|
|
18
|
-
package Package module for distribution
|
|
19
|
-
update Update CLI/pgpm (installs pgpm by default)
|
|
20
|
-
cache Manage cached templates (clean)
|
|
21
|
-
upgrade-modules Upgrade installed pgpm modules to latest versions
|
|
22
|
-
|
|
23
|
-
Development Tools:
|
|
10
|
+
GraphQL Server:
|
|
24
11
|
server Start a GraphQL server
|
|
25
12
|
explorer Launch GraphiQL explorer interface
|
|
26
|
-
docker Manage PostgreSQL Docker containers (start/stop)
|
|
27
|
-
export Export database migrations from existing databases
|
|
28
|
-
env Display environment configuration
|
|
29
13
|
|
|
30
14
|
Code Generation:
|
|
31
15
|
codegen Generate TypeScript types and SDK from GraphQL schema
|
|
32
16
|
get-graphql-schema Fetch or build GraphQL schema SDL
|
|
33
17
|
|
|
34
|
-
Database Administration:
|
|
35
|
-
kill Terminate database connections and optionally drop databases
|
|
36
|
-
install Install pgpm modules
|
|
37
|
-
tag Add tags to changes for versioning
|
|
38
|
-
clear Clear database state
|
|
39
|
-
remove Remove database changes
|
|
40
|
-
analyze Analyze database structure
|
|
41
|
-
rename Rename database changes
|
|
42
|
-
admin-users Manage admin users
|
|
43
|
-
|
|
44
|
-
Testing:
|
|
45
|
-
test-packages Run integration tests on all workspace packages
|
|
46
|
-
|
|
47
|
-
Migration Tools:
|
|
48
|
-
migrate Migration management subcommands
|
|
49
|
-
init Initialize migration tracking
|
|
50
|
-
status Show migration status
|
|
51
|
-
list List all changes
|
|
52
|
-
deps Show change dependencies
|
|
53
|
-
|
|
54
18
|
Global Options:
|
|
55
19
|
-h, --help Display this help information
|
|
56
20
|
-v, --version Display version information
|
|
57
21
|
--cwd <directory> Working directory (default: current directory)
|
|
58
22
|
|
|
59
23
|
Individual Command Help:
|
|
60
|
-
|
|
61
|
-
|
|
24
|
+
cnc <command> --help Display detailed help for specific command
|
|
25
|
+
cnc <command> -h Display detailed help for specific command
|
|
62
26
|
|
|
63
27
|
Examples:
|
|
64
|
-
cnc
|
|
65
|
-
cnc server --port 8080
|
|
66
|
-
cnc
|
|
28
|
+
cnc server Start GraphQL server
|
|
29
|
+
cnc server --port 8080 Start server on custom port
|
|
30
|
+
cnc explorer Launch GraphiQL explorer
|
|
31
|
+
cnc codegen --schema schema.graphql Generate types from schema
|
|
32
|
+
cnc get-graphql-schema --out schema.graphql Export schema SDL
|
|
33
|
+
|
|
34
|
+
Database Operations:
|
|
35
|
+
For database migrations, packages, and deployment, use pgpm:
|
|
36
|
+
https://pgpm.io
|
|
67
37
|
`;
|
package/utils/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { extractFirst } from '
|
|
2
|
-
export { cliExitWithError } from '
|
|
1
|
+
export { extractFirst } from './argv';
|
|
2
|
+
export { cliExitWithError } from './cli-error';
|
|
3
3
|
export { usageText } from './display';
|
package/utils/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.usageText = exports.cliExitWithError = exports.extractFirst = void 0;
|
|
4
|
-
var
|
|
5
|
-
Object.defineProperty(exports, "extractFirst", { enumerable: true, get: function () { return
|
|
6
|
-
var
|
|
7
|
-
Object.defineProperty(exports, "cliExitWithError", { enumerable: true, get: function () { return
|
|
4
|
+
var argv_1 = require("./argv");
|
|
5
|
+
Object.defineProperty(exports, "extractFirst", { enumerable: true, get: function () { return argv_1.extractFirst; } });
|
|
6
|
+
var cli_error_1 = require("./cli-error");
|
|
7
|
+
Object.defineProperty(exports, "cliExitWithError", { enumerable: true, get: function () { return cli_error_1.cliExitWithError; } });
|
|
8
8
|
var display_1 = require("./display");
|
|
9
9
|
Object.defineProperty(exports, "usageText", { enumerable: true, get: function () { return display_1.usageText; } });
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface CheckForUpdatesOptions {
|
|
2
|
+
pkgName?: string;
|
|
3
|
+
pkgVersion?: string;
|
|
4
|
+
command?: string;
|
|
5
|
+
now?: number;
|
|
6
|
+
updateCommand?: string;
|
|
7
|
+
toolName?: string;
|
|
8
|
+
key?: string;
|
|
9
|
+
}
|
|
10
|
+
interface UpdateCheckConfig {
|
|
11
|
+
lastCheckedAt: number;
|
|
12
|
+
latestKnownVersion: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function checkForUpdates(options?: CheckForUpdatesOptions): Promise<UpdateCheckConfig | null>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
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.checkForUpdates = checkForUpdates;
|
|
7
|
+
const find_and_require_package_json_1 = require("find-and-require-package-json");
|
|
8
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const log = new logger_1.Logger('update-check');
|
|
13
|
+
const UPDATE_CHECK_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
|
|
14
|
+
const shouldSkip = (command) => {
|
|
15
|
+
if (process.env.PGPM_SKIP_UPDATE_CHECK)
|
|
16
|
+
return true;
|
|
17
|
+
if (process.env.CI === 'true')
|
|
18
|
+
return true;
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
function getConfigPath(toolName, key) {
|
|
22
|
+
const configDir = path_1.default.join(os_1.default.homedir(), `.${toolName}`);
|
|
23
|
+
return path_1.default.join(configDir, `${key}.json`);
|
|
24
|
+
}
|
|
25
|
+
function readConfig(toolName, key) {
|
|
26
|
+
try {
|
|
27
|
+
const configPath = getConfigPath(toolName, key);
|
|
28
|
+
if (!fs_1.default.existsSync(configPath))
|
|
29
|
+
return null;
|
|
30
|
+
const content = fs_1.default.readFileSync(configPath, 'utf8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function writeConfig(toolName, key, config) {
|
|
38
|
+
try {
|
|
39
|
+
const configPath = getConfigPath(toolName, key);
|
|
40
|
+
const configDir = path_1.default.dirname(configPath);
|
|
41
|
+
if (!fs_1.default.existsSync(configDir)) {
|
|
42
|
+
fs_1.default.mkdirSync(configDir, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Ignore write errors
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function fetchLatestVersion(pkgName) {
|
|
51
|
+
try {
|
|
52
|
+
const response = await fetch(`https://registry.npmjs.org/${pkgName}/latest`);
|
|
53
|
+
if (!response.ok)
|
|
54
|
+
return null;
|
|
55
|
+
const data = await response.json();
|
|
56
|
+
return data.version || null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function compareVersions(current, latest) {
|
|
63
|
+
const currentParts = current.replace(/^v/, '').split('.').map(Number);
|
|
64
|
+
const latestParts = latest.replace(/^v/, '').split('.').map(Number);
|
|
65
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
66
|
+
const c = currentParts[i] || 0;
|
|
67
|
+
const l = latestParts[i] || 0;
|
|
68
|
+
if (c < l)
|
|
69
|
+
return -1;
|
|
70
|
+
if (c > l)
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
async function checkForUpdates(options = {}) {
|
|
76
|
+
const { pkgName = '@constructive-io/cli', pkgVersion = (0, find_and_require_package_json_1.findAndRequirePackageJson)(__dirname).version, command, now = Date.now(), key = 'update-check', toolName = 'constructive' } = options;
|
|
77
|
+
if (shouldSkip(command)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const existing = readConfig(toolName, key);
|
|
82
|
+
let latestKnownVersion = existing?.latestKnownVersion ?? pkgVersion;
|
|
83
|
+
const needsCheck = !existing?.lastCheckedAt || (now - existing.lastCheckedAt) > UPDATE_CHECK_TTL_MS;
|
|
84
|
+
if (needsCheck) {
|
|
85
|
+
const fetched = await fetchLatestVersion(pkgName);
|
|
86
|
+
if (fetched) {
|
|
87
|
+
latestKnownVersion = fetched;
|
|
88
|
+
}
|
|
89
|
+
writeConfig(toolName, key, {
|
|
90
|
+
lastCheckedAt: now,
|
|
91
|
+
latestKnownVersion
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const comparison = compareVersions(pkgVersion, latestKnownVersion);
|
|
95
|
+
const isOutdated = comparison < 0;
|
|
96
|
+
if (isOutdated) {
|
|
97
|
+
const updateInstruction = options.updateCommand ?? `Run npm i -g ${pkgName}@latest to upgrade.`;
|
|
98
|
+
log.warn(`A new version of ${pkgName} is available (current ${pkgVersion}, latest ${latestKnownVersion}). ${updateInstruction}`);
|
|
99
|
+
writeConfig(toolName, key, {
|
|
100
|
+
lastCheckedAt: now,
|
|
101
|
+
latestKnownVersion
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
lastCheckedAt: now,
|
|
106
|
+
latestKnownVersion
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
log.debug('Update check skipped due to error:', error);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|