pgpm 2.5.0 → 2.6.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 +17 -22
- package/commands/install.js +21 -4
- package/commands/{upgrade-modules.js → upgrade.js} +41 -44
- package/commands.js +3 -2
- package/esm/commands/install.js +22 -5
- package/esm/commands/{upgrade-modules.js → upgrade.js} +41 -44
- package/esm/commands.js +3 -2
- package/esm/utils/display.js +1 -1
- package/package.json +6 -6
- package/utils/display.d.ts +1 -1
- package/utils/display.js +1 -1
- /package/commands/{upgrade-modules.d.ts → upgrade.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# **pgpm — a Postgres Package Manager**
|
|
2
2
|
|
|
3
|
+
<p align="center" width="100%">
|
|
4
|
+
<img height="250" src="https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center" width="100%">
|
|
8
|
+
<a href="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml">
|
|
9
|
+
<img height="20" src="https://github.com/constructive-io/constructive/actions/workflows/run-tests.yaml/badge.svg" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/constructive-io/constructive/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/pgpm"><img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/constructive?filename=pgpm%2Fcli%2Fpackage.json"/></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
3
15
|
**A modern CLI for modular PostgreSQL development.**
|
|
4
16
|
|
|
5
17
|
`pgpm` is a focused command-line tool for PostgreSQL database migrations and package management. It provides the core functionality for managing database schemas, migrations, and module dependencies.
|
|
@@ -446,9 +458,14 @@ Common issues and solutions for pgpm, PostgreSQL, and testing.
|
|
|
446
458
|
|
|
447
459
|
## Related Constructive Tooling
|
|
448
460
|
|
|
461
|
+
### 📦 Package Management
|
|
462
|
+
|
|
463
|
+
* [pgpm](https://github.com/constructive-io/constructive/tree/main/pgpm/pgpm): **🖥️ PostgreSQL Package Manager** for modular Postgres development. Works with database workspaces, scaffolding, migrations, seeding, and installing database packages.
|
|
464
|
+
|
|
449
465
|
### 🧪 Testing
|
|
450
466
|
|
|
451
467
|
* [pgsql-test](https://github.com/constructive-io/constructive/tree/main/postgres/pgsql-test): **📊 Isolated testing environments** with per-test transaction rollbacks—ideal for integration tests, complex migrations, and RLS simulation.
|
|
468
|
+
* [pgsql-seed](https://github.com/constructive-io/constructive/tree/main/postgres/pgsql-seed): **🌱 PostgreSQL seeding utilities** for CSV, JSON, SQL data loading, and pgpm deployment.
|
|
452
469
|
* [supabase-test](https://github.com/constructive-io/constructive/tree/main/postgres/supabase-test): **🧪 Supabase-native test harness** preconfigured for the local Supabase stack—per-test rollbacks, JWT/role context helpers, and CI/GitHub Actions ready.
|
|
453
470
|
* [graphile-test](https://github.com/constructive-io/constructive/tree/main/graphile/graphile-test): **🔐 Authentication mocking** for Graphile-focused test helpers and emulating row-level security contexts.
|
|
454
471
|
* [pg-query-context](https://github.com/constructive-io/constructive/tree/main/postgres/pg-query-context): **🔒 Session context injection** to add session-local context (e.g., `SET LOCAL`) into queries—ideal for setting `role`, `jwt.claims`, and other session settings.
|
|
@@ -462,28 +479,6 @@ Common issues and solutions for pgpm, PostgreSQL, and testing.
|
|
|
462
479
|
* [@pgsql/types](https://www.npmjs.com/package/@pgsql/types): **📝 Type definitions** for PostgreSQL AST nodes in TypeScript.
|
|
463
480
|
* [@pgsql/utils](https://www.npmjs.com/package/@pgsql/utils): **🛠️ AST utilities** for constructing and transforming PostgreSQL syntax trees.
|
|
464
481
|
|
|
465
|
-
### 🚀 API & Dev Tools
|
|
466
|
-
|
|
467
|
-
* [@constructive-io/graphql-server](https://github.com/constructive-io/constructive/tree/main/graphql/server): **⚡ Express-based API server** powered by PostGraphile to expose a secure, scalable GraphQL API over your Postgres database.
|
|
468
|
-
* [@constructive-io/graphql-explorer](https://github.com/constructive-io/constructive/tree/main/graphql/explorer): **🔎 Visual API explorer** with GraphiQL for browsing across all databases and schemas—useful for debugging, documentation, and API prototyping.
|
|
469
|
-
|
|
470
|
-
### 🔁 Streaming & Uploads
|
|
471
|
-
|
|
472
|
-
* [etag-hash](https://github.com/constructive-io/constructive/tree/main/streaming/etag-hash): **🏷️ S3-compatible ETags** created by streaming and hashing file uploads in chunks.
|
|
473
|
-
* [etag-stream](https://github.com/constructive-io/constructive/tree/main/streaming/etag-stream): **🔄 ETag computation** via Node stream transformer during upload or transfer.
|
|
474
|
-
* [uuid-hash](https://github.com/constructive-io/constructive/tree/main/streaming/uuid-hash): **🆔 Deterministic UUIDs** generated from hashed content, great for deduplication and asset referencing.
|
|
475
|
-
* [uuid-stream](https://github.com/constructive-io/constructive/tree/main/streaming/uuid-stream): **🌊 Streaming UUID generation** based on piped file content—ideal for upload pipelines.
|
|
476
|
-
* [@constructive-io/s3-streamer](https://github.com/constructive-io/constructive/tree/main/streaming/s3-streamer): **📤 Direct S3 streaming** for large files with support for metadata injection and content validation.
|
|
477
|
-
* [@constructive-io/upload-names](https://github.com/constructive-io/constructive/tree/main/streaming/upload-names): **📂 Collision-resistant filenames** utility for structured and unique file names for uploads.
|
|
478
|
-
|
|
479
|
-
### 🧰 CLI & Codegen
|
|
480
|
-
|
|
481
|
-
* [pgpm](https://github.com/constructive-io/constructive/tree/main/pgpm/pgpm): **🖥️ PostgreSQL Package Manager** for modular Postgres development. Works with database workspaces, scaffolding, migrations, seeding, and installing database packages.
|
|
482
|
-
* [@constructive-io/cli](https://github.com/constructive-io/constructive/tree/main/packages/cli): **🖥️ Command-line toolkit** for managing Constructive projects—supports database scaffolding, migrations, seeding, code generation, and automation.
|
|
483
|
-
* [@constructive-io/graphql-codegen](https://github.com/constructive-io/constructive/tree/main/graphql/codegen): **✨ GraphQL code generation** (types, operations, SDK) from schema/endpoint introspection.
|
|
484
|
-
* [@constructive-io/query-builder](https://github.com/constructive-io/constructive/tree/main/packages/query-builder): **🏗️ SQL constructor** providing a robust TypeScript-based query builder for dynamic generation of `SELECT`, `INSERT`, `UPDATE`, `DELETE`, and stored procedure calls—supports advanced SQL features like `JOIN`, `GROUP BY`, and schema-qualified queries.
|
|
485
|
-
* [@constructive-io/graphql-query](https://github.com/constructive-io/constructive/tree/main/graphql/query): **🧩 Fluent GraphQL builder** for PostGraphile schemas. ⚡ Schema-aware via introspection, 🧩 composable and ergonomic for building deeply nested queries.
|
|
486
|
-
|
|
487
482
|
## Credits
|
|
488
483
|
|
|
489
484
|
**🛠 Built by the [Constructive](https://constructive.io) team — creators of modular Postgres tooling for secure, composable backends. If you like our work, contribute on [GitHub](https://github.com/constructive-io).**
|
package/commands/install.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@pgpmjs/core");
|
|
4
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
5
|
+
const logger = new logger_1.Logger('pgpm');
|
|
4
6
|
const installUsageText = `
|
|
5
7
|
Install Command:
|
|
6
8
|
|
|
7
|
-
pgpm install
|
|
9
|
+
pgpm install [package]...
|
|
8
10
|
|
|
9
11
|
Install pgpm modules into current module.
|
|
10
12
|
|
|
13
|
+
When called without arguments, installs any missing modules that are
|
|
14
|
+
listed in the module's .control file but not yet installed in the workspace.
|
|
15
|
+
|
|
11
16
|
Arguments:
|
|
12
|
-
package One or more package names to install
|
|
17
|
+
package One or more package names to install (optional)
|
|
13
18
|
|
|
14
19
|
Options:
|
|
15
20
|
--help, -h Show this help message
|
|
16
21
|
--cwd <directory> Working directory (default: current directory)
|
|
17
22
|
|
|
18
23
|
Examples:
|
|
24
|
+
pgpm install Install missing modules from .control file
|
|
19
25
|
pgpm install @pgpm/base32 Install single package
|
|
20
|
-
pgpm install @pgpm/base32 @pgpm/utils
|
|
26
|
+
pgpm install @pgpm/base32 @pgpm/utils Install multiple packages
|
|
21
27
|
`;
|
|
22
28
|
exports.default = async (argv, prompter, _options) => {
|
|
23
29
|
// Show usage if explicitly requested
|
|
@@ -30,8 +36,19 @@ exports.default = async (argv, prompter, _options) => {
|
|
|
30
36
|
if (!project.isInModule()) {
|
|
31
37
|
throw new Error('You must run this command inside a PGPM module.');
|
|
32
38
|
}
|
|
39
|
+
// If no packages specified, install missing modules from .control file
|
|
33
40
|
if (argv._.length === 0) {
|
|
34
|
-
|
|
41
|
+
const requiredExtensions = project.getRequiredModules();
|
|
42
|
+
const installedModules = project.getWorkspaceInstalledModules();
|
|
43
|
+
const missingModules = (0, core_1.getMissingInstallableModules)(requiredExtensions, installedModules);
|
|
44
|
+
if (missingModules.length === 0) {
|
|
45
|
+
logger.success('All modules are already installed.');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const missingNames = missingModules.map(m => m.npmName);
|
|
49
|
+
logger.info(`Installing missing modules: ${missingNames.join(', ')}`);
|
|
50
|
+
await project.installModules(...missingNames);
|
|
51
|
+
return;
|
|
35
52
|
}
|
|
36
53
|
await project.installModules(...argv._);
|
|
37
54
|
};
|
|
@@ -2,29 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@pgpmjs/core");
|
|
4
4
|
const logger_1 = require("@pgpmjs/logger");
|
|
5
|
+
const inquirerer_1 = require("inquirerer");
|
|
5
6
|
const npm_version_1 = require("../utils/npm-version");
|
|
6
|
-
const log = new logger_1.Logger('upgrade
|
|
7
|
-
const
|
|
8
|
-
Upgrade
|
|
7
|
+
const log = new logger_1.Logger('upgrade');
|
|
8
|
+
const upgradeUsageText = `
|
|
9
|
+
Upgrade Command:
|
|
9
10
|
|
|
10
|
-
pgpm upgrade
|
|
11
|
+
pgpm upgrade [PACKAGE...] [OPTIONS]
|
|
11
12
|
|
|
12
13
|
Upgrade installed pgpm modules to their latest versions from npm.
|
|
14
|
+
When used without arguments, upgrades all modules.
|
|
13
15
|
|
|
14
16
|
Options:
|
|
15
17
|
--help, -h Show this help message
|
|
16
18
|
--cwd <directory> Working directory (default: current directory)
|
|
17
|
-
--
|
|
19
|
+
-i, --interactive Show outdated modules and select which ones to upgrade
|
|
18
20
|
--dry-run Show what would be upgraded without making changes
|
|
19
|
-
--modules <names> Comma-separated list of specific modules to upgrade
|
|
20
21
|
--workspace Upgrade modules across all packages in the workspace
|
|
21
22
|
|
|
22
23
|
Examples:
|
|
23
|
-
pgpm upgrade
|
|
24
|
-
pgpm upgrade-
|
|
25
|
-
pgpm upgrade
|
|
26
|
-
pgpm upgrade
|
|
27
|
-
pgpm upgrade
|
|
24
|
+
pgpm upgrade Upgrade all installed modules
|
|
25
|
+
pgpm upgrade -i Interactive selection of modules to upgrade
|
|
26
|
+
pgpm upgrade @pgpm/base32 Upgrade specific module
|
|
27
|
+
pgpm upgrade @pgpm/base32 @pgpm/uuid Upgrade multiple specific modules
|
|
28
|
+
pgpm upgrade --dry-run Preview available upgrades
|
|
29
|
+
pgpm upgrade --workspace Upgrade all modules across the entire workspace
|
|
30
|
+
pgpm up Alias for upgrade
|
|
28
31
|
`;
|
|
29
32
|
async function fetchModuleVersions(installedVersions) {
|
|
30
33
|
const moduleNames = Object.keys(installedVersions);
|
|
@@ -41,7 +44,7 @@ async function fetchModuleVersions(installedVersions) {
|
|
|
41
44
|
}
|
|
42
45
|
return results;
|
|
43
46
|
}
|
|
44
|
-
async function upgradeModulesForProject(project, argv, prompter, dryRun,
|
|
47
|
+
async function upgradeModulesForProject(project, argv, prompter, dryRun, interactive, specificModules, moduleName) {
|
|
45
48
|
const { installed, installedVersions } = project.getInstalledModules();
|
|
46
49
|
if (installed.length === 0) {
|
|
47
50
|
if (moduleName) {
|
|
@@ -53,9 +56,12 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
53
56
|
return false;
|
|
54
57
|
}
|
|
55
58
|
const prefix = moduleName ? `[${moduleName}] ` : '';
|
|
56
|
-
|
|
59
|
+
// Use spinner while checking for updates
|
|
60
|
+
const spinner = (0, inquirerer_1.createSpinner)(`${prefix}Checking ${installed.length} installed module(s) for updates...`);
|
|
61
|
+
spinner.start();
|
|
57
62
|
const moduleVersions = await fetchModuleVersions(installedVersions);
|
|
58
63
|
const modulesWithUpdates = moduleVersions.filter(m => m.hasUpdate);
|
|
64
|
+
spinner.succeed(`${prefix}Found ${modulesWithUpdates.length} module(s) with updates available`);
|
|
59
65
|
if (modulesWithUpdates.length === 0) {
|
|
60
66
|
log.success(`${prefix}All modules are already up to date.`);
|
|
61
67
|
return false;
|
|
@@ -70,10 +76,8 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
70
76
|
return true;
|
|
71
77
|
}
|
|
72
78
|
let modulesToUpgrade;
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
else if (specificModules) {
|
|
79
|
+
if (specificModules && specificModules.length > 0) {
|
|
80
|
+
// Specific modules provided as positional arguments
|
|
77
81
|
modulesToUpgrade = modulesWithUpdates
|
|
78
82
|
.filter(m => specificModules.includes(m.name))
|
|
79
83
|
.map(m => m.name);
|
|
@@ -82,32 +86,24 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
82
86
|
return false;
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
|
-
else {
|
|
86
|
-
|
|
89
|
+
else if (interactive) {
|
|
90
|
+
// Interactive mode: use pnpm-style upgrade UI
|
|
91
|
+
const packages = modulesWithUpdates.map(mod => ({
|
|
87
92
|
name: mod.name,
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
current: mod.currentVersion,
|
|
94
|
+
latest: mod.latestVersion,
|
|
95
|
+
type: 'dependencies'
|
|
90
96
|
}));
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
name: 'selectedModules',
|
|
94
|
-
message: `${prefix}Select modules to upgrade:`,
|
|
95
|
-
type: 'checkbox',
|
|
96
|
-
options: options.map(o => o.message),
|
|
97
|
-
default: options.map(o => o.message)
|
|
98
|
-
}
|
|
99
|
-
];
|
|
100
|
-
const answers = await prompter.prompt(argv, questions);
|
|
101
|
-
const selectedOptions = answers.selectedModules
|
|
102
|
-
.filter(opt => opt.selected)
|
|
103
|
-
.map(opt => opt.name);
|
|
104
|
-
modulesToUpgrade = modulesWithUpdates
|
|
105
|
-
.filter(mod => selectedOptions.includes(`${mod.name} (${mod.currentVersion} -> ${mod.latestVersion})`))
|
|
106
|
-
.map(m => m.name);
|
|
107
|
-
if (modulesToUpgrade.length === 0) {
|
|
97
|
+
const result = await (0, inquirerer_1.upgradePrompt)(packages, 10);
|
|
98
|
+
if (result.updates.length === 0) {
|
|
108
99
|
log.info(`${prefix}No modules selected for upgrade.`);
|
|
109
100
|
return false;
|
|
110
101
|
}
|
|
102
|
+
modulesToUpgrade = result.updates.map(u => u.name);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Default behavior: upgrade all modules with updates (like pnpm upgrade)
|
|
106
|
+
modulesToUpgrade = modulesWithUpdates.map(m => m.name);
|
|
111
107
|
}
|
|
112
108
|
log.info(`\n${prefix}Upgrading ${modulesToUpgrade.length} module(s)...`);
|
|
113
109
|
await project.upgradeModules({ modules: modulesToUpgrade });
|
|
@@ -116,15 +112,16 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
116
112
|
}
|
|
117
113
|
exports.default = async (argv, prompter, _options) => {
|
|
118
114
|
if (argv.help || argv.h) {
|
|
119
|
-
console.log(
|
|
115
|
+
console.log(upgradeUsageText);
|
|
120
116
|
process.exit(0);
|
|
121
117
|
}
|
|
122
118
|
const { cwd = process.cwd() } = argv;
|
|
123
119
|
const dryRun = Boolean(argv['dry-run']);
|
|
124
|
-
const
|
|
120
|
+
const interactive = Boolean(argv.i || argv.interactive);
|
|
125
121
|
const workspaceMode = Boolean(argv.workspace);
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
// Get specific modules from positional arguments (argv._)
|
|
123
|
+
const specificModules = argv._ && argv._.length > 0
|
|
124
|
+
? argv._.map((m) => String(m).trim())
|
|
128
125
|
: undefined;
|
|
129
126
|
const project = new core_1.PgpmPackage(cwd);
|
|
130
127
|
if (workspaceMode) {
|
|
@@ -140,7 +137,7 @@ exports.default = async (argv, prompter, _options) => {
|
|
|
140
137
|
let anyUpgraded = false;
|
|
141
138
|
for (const moduleProject of modules) {
|
|
142
139
|
const moduleName = moduleProject.getModuleName();
|
|
143
|
-
const upgraded = await upgradeModulesForProject(moduleProject, argv, prompter, dryRun,
|
|
140
|
+
const upgraded = await upgradeModulesForProject(moduleProject, argv, prompter, dryRun, interactive, specificModules, moduleName);
|
|
144
141
|
if (upgraded) {
|
|
145
142
|
anyUpgraded = true;
|
|
146
143
|
}
|
|
@@ -154,6 +151,6 @@ exports.default = async (argv, prompter, _options) => {
|
|
|
154
151
|
if (!project.isInModule()) {
|
|
155
152
|
throw new Error('You must run this command inside a PGPM module. Use --workspace to upgrade all modules in the workspace.');
|
|
156
153
|
}
|
|
157
|
-
await upgradeModulesForProject(project, argv, prompter, dryRun,
|
|
154
|
+
await upgradeModulesForProject(project, argv, prompter, dryRun, interactive, specificModules);
|
|
158
155
|
}
|
|
159
156
|
};
|
package/commands.js
CHANGED
|
@@ -24,7 +24,7 @@ const migrate_1 = __importDefault(require("./commands/migrate"));
|
|
|
24
24
|
const package_1 = __importDefault(require("./commands/package"));
|
|
25
25
|
const plan_1 = __importDefault(require("./commands/plan"));
|
|
26
26
|
const update_1 = __importDefault(require("./commands/update"));
|
|
27
|
-
const
|
|
27
|
+
const upgrade_1 = __importDefault(require("./commands/upgrade"));
|
|
28
28
|
const remove_1 = __importDefault(require("./commands/remove"));
|
|
29
29
|
const rename_1 = __importDefault(require("./commands/rename"));
|
|
30
30
|
const revert_1 = __importDefault(require("./commands/revert"));
|
|
@@ -66,7 +66,8 @@ const createPgpmCommandMap = (skipPgTeardown = false) => {
|
|
|
66
66
|
analyze: pgt(analyze_1.default),
|
|
67
67
|
rename: pgt(rename_1.default),
|
|
68
68
|
'test-packages': pgt(test_packages_1.default),
|
|
69
|
-
|
|
69
|
+
upgrade: pgt(upgrade_1.default),
|
|
70
|
+
up: pgt(upgrade_1.default),
|
|
70
71
|
cache: cache_1.default,
|
|
71
72
|
update: update_1.default
|
|
72
73
|
};
|
package/esm/commands/install.js
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
import { PgpmPackage } from '@pgpmjs/core';
|
|
1
|
+
import { getMissingInstallableModules, PgpmPackage } from '@pgpmjs/core';
|
|
2
|
+
import { Logger } from '@pgpmjs/logger';
|
|
3
|
+
const logger = new Logger('pgpm');
|
|
2
4
|
const installUsageText = `
|
|
3
5
|
Install Command:
|
|
4
6
|
|
|
5
|
-
pgpm install
|
|
7
|
+
pgpm install [package]...
|
|
6
8
|
|
|
7
9
|
Install pgpm modules into current module.
|
|
8
10
|
|
|
11
|
+
When called without arguments, installs any missing modules that are
|
|
12
|
+
listed in the module's .control file but not yet installed in the workspace.
|
|
13
|
+
|
|
9
14
|
Arguments:
|
|
10
|
-
package One or more package names to install
|
|
15
|
+
package One or more package names to install (optional)
|
|
11
16
|
|
|
12
17
|
Options:
|
|
13
18
|
--help, -h Show this help message
|
|
14
19
|
--cwd <directory> Working directory (default: current directory)
|
|
15
20
|
|
|
16
21
|
Examples:
|
|
22
|
+
pgpm install Install missing modules from .control file
|
|
17
23
|
pgpm install @pgpm/base32 Install single package
|
|
18
|
-
pgpm install @pgpm/base32 @pgpm/utils
|
|
24
|
+
pgpm install @pgpm/base32 @pgpm/utils Install multiple packages
|
|
19
25
|
`;
|
|
20
26
|
export default async (argv, prompter, _options) => {
|
|
21
27
|
// Show usage if explicitly requested
|
|
@@ -28,8 +34,19 @@ export default async (argv, prompter, _options) => {
|
|
|
28
34
|
if (!project.isInModule()) {
|
|
29
35
|
throw new Error('You must run this command inside a PGPM module.');
|
|
30
36
|
}
|
|
37
|
+
// If no packages specified, install missing modules from .control file
|
|
31
38
|
if (argv._.length === 0) {
|
|
32
|
-
|
|
39
|
+
const requiredExtensions = project.getRequiredModules();
|
|
40
|
+
const installedModules = project.getWorkspaceInstalledModules();
|
|
41
|
+
const missingModules = getMissingInstallableModules(requiredExtensions, installedModules);
|
|
42
|
+
if (missingModules.length === 0) {
|
|
43
|
+
logger.success('All modules are already installed.');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const missingNames = missingModules.map(m => m.npmName);
|
|
47
|
+
logger.info(`Installing missing modules: ${missingNames.join(', ')}`);
|
|
48
|
+
await project.installModules(...missingNames);
|
|
49
|
+
return;
|
|
33
50
|
}
|
|
34
51
|
await project.installModules(...argv._);
|
|
35
52
|
};
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
import { PgpmPackage } from '@pgpmjs/core';
|
|
2
2
|
import { Logger } from '@pgpmjs/logger';
|
|
3
|
+
import { upgradePrompt, createSpinner } from 'inquirerer';
|
|
3
4
|
import { fetchLatestVersion } from '../utils/npm-version';
|
|
4
|
-
const log = new Logger('upgrade
|
|
5
|
-
const
|
|
6
|
-
Upgrade
|
|
5
|
+
const log = new Logger('upgrade');
|
|
6
|
+
const upgradeUsageText = `
|
|
7
|
+
Upgrade Command:
|
|
7
8
|
|
|
8
|
-
pgpm upgrade
|
|
9
|
+
pgpm upgrade [PACKAGE...] [OPTIONS]
|
|
9
10
|
|
|
10
11
|
Upgrade installed pgpm modules to their latest versions from npm.
|
|
12
|
+
When used without arguments, upgrades all modules.
|
|
11
13
|
|
|
12
14
|
Options:
|
|
13
15
|
--help, -h Show this help message
|
|
14
16
|
--cwd <directory> Working directory (default: current directory)
|
|
15
|
-
--
|
|
17
|
+
-i, --interactive Show outdated modules and select which ones to upgrade
|
|
16
18
|
--dry-run Show what would be upgraded without making changes
|
|
17
|
-
--modules <names> Comma-separated list of specific modules to upgrade
|
|
18
19
|
--workspace Upgrade modules across all packages in the workspace
|
|
19
20
|
|
|
20
21
|
Examples:
|
|
21
|
-
pgpm upgrade
|
|
22
|
-
pgpm upgrade-
|
|
23
|
-
pgpm upgrade
|
|
24
|
-
pgpm upgrade
|
|
25
|
-
pgpm upgrade
|
|
22
|
+
pgpm upgrade Upgrade all installed modules
|
|
23
|
+
pgpm upgrade -i Interactive selection of modules to upgrade
|
|
24
|
+
pgpm upgrade @pgpm/base32 Upgrade specific module
|
|
25
|
+
pgpm upgrade @pgpm/base32 @pgpm/uuid Upgrade multiple specific modules
|
|
26
|
+
pgpm upgrade --dry-run Preview available upgrades
|
|
27
|
+
pgpm upgrade --workspace Upgrade all modules across the entire workspace
|
|
28
|
+
pgpm up Alias for upgrade
|
|
26
29
|
`;
|
|
27
30
|
async function fetchModuleVersions(installedVersions) {
|
|
28
31
|
const moduleNames = Object.keys(installedVersions);
|
|
@@ -39,7 +42,7 @@ async function fetchModuleVersions(installedVersions) {
|
|
|
39
42
|
}
|
|
40
43
|
return results;
|
|
41
44
|
}
|
|
42
|
-
async function upgradeModulesForProject(project, argv, prompter, dryRun,
|
|
45
|
+
async function upgradeModulesForProject(project, argv, prompter, dryRun, interactive, specificModules, moduleName) {
|
|
43
46
|
const { installed, installedVersions } = project.getInstalledModules();
|
|
44
47
|
if (installed.length === 0) {
|
|
45
48
|
if (moduleName) {
|
|
@@ -51,9 +54,12 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
51
54
|
return false;
|
|
52
55
|
}
|
|
53
56
|
const prefix = moduleName ? `[${moduleName}] ` : '';
|
|
54
|
-
|
|
57
|
+
// Use spinner while checking for updates
|
|
58
|
+
const spinner = createSpinner(`${prefix}Checking ${installed.length} installed module(s) for updates...`);
|
|
59
|
+
spinner.start();
|
|
55
60
|
const moduleVersions = await fetchModuleVersions(installedVersions);
|
|
56
61
|
const modulesWithUpdates = moduleVersions.filter(m => m.hasUpdate);
|
|
62
|
+
spinner.succeed(`${prefix}Found ${modulesWithUpdates.length} module(s) with updates available`);
|
|
57
63
|
if (modulesWithUpdates.length === 0) {
|
|
58
64
|
log.success(`${prefix}All modules are already up to date.`);
|
|
59
65
|
return false;
|
|
@@ -68,10 +74,8 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
68
74
|
return true;
|
|
69
75
|
}
|
|
70
76
|
let modulesToUpgrade;
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
else if (specificModules) {
|
|
77
|
+
if (specificModules && specificModules.length > 0) {
|
|
78
|
+
// Specific modules provided as positional arguments
|
|
75
79
|
modulesToUpgrade = modulesWithUpdates
|
|
76
80
|
.filter(m => specificModules.includes(m.name))
|
|
77
81
|
.map(m => m.name);
|
|
@@ -80,32 +84,24 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
80
84
|
return false;
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
else {
|
|
84
|
-
|
|
87
|
+
else if (interactive) {
|
|
88
|
+
// Interactive mode: use pnpm-style upgrade UI
|
|
89
|
+
const packages = modulesWithUpdates.map(mod => ({
|
|
85
90
|
name: mod.name,
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
current: mod.currentVersion,
|
|
92
|
+
latest: mod.latestVersion,
|
|
93
|
+
type: 'dependencies'
|
|
88
94
|
}));
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
name: 'selectedModules',
|
|
92
|
-
message: `${prefix}Select modules to upgrade:`,
|
|
93
|
-
type: 'checkbox',
|
|
94
|
-
options: options.map(o => o.message),
|
|
95
|
-
default: options.map(o => o.message)
|
|
96
|
-
}
|
|
97
|
-
];
|
|
98
|
-
const answers = await prompter.prompt(argv, questions);
|
|
99
|
-
const selectedOptions = answers.selectedModules
|
|
100
|
-
.filter(opt => opt.selected)
|
|
101
|
-
.map(opt => opt.name);
|
|
102
|
-
modulesToUpgrade = modulesWithUpdates
|
|
103
|
-
.filter(mod => selectedOptions.includes(`${mod.name} (${mod.currentVersion} -> ${mod.latestVersion})`))
|
|
104
|
-
.map(m => m.name);
|
|
105
|
-
if (modulesToUpgrade.length === 0) {
|
|
95
|
+
const result = await upgradePrompt(packages, 10);
|
|
96
|
+
if (result.updates.length === 0) {
|
|
106
97
|
log.info(`${prefix}No modules selected for upgrade.`);
|
|
107
98
|
return false;
|
|
108
99
|
}
|
|
100
|
+
modulesToUpgrade = result.updates.map(u => u.name);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Default behavior: upgrade all modules with updates (like pnpm upgrade)
|
|
104
|
+
modulesToUpgrade = modulesWithUpdates.map(m => m.name);
|
|
109
105
|
}
|
|
110
106
|
log.info(`\n${prefix}Upgrading ${modulesToUpgrade.length} module(s)...`);
|
|
111
107
|
await project.upgradeModules({ modules: modulesToUpgrade });
|
|
@@ -114,15 +110,16 @@ async function upgradeModulesForProject(project, argv, prompter, dryRun, upgrade
|
|
|
114
110
|
}
|
|
115
111
|
export default async (argv, prompter, _options) => {
|
|
116
112
|
if (argv.help || argv.h) {
|
|
117
|
-
console.log(
|
|
113
|
+
console.log(upgradeUsageText);
|
|
118
114
|
process.exit(0);
|
|
119
115
|
}
|
|
120
116
|
const { cwd = process.cwd() } = argv;
|
|
121
117
|
const dryRun = Boolean(argv['dry-run']);
|
|
122
|
-
const
|
|
118
|
+
const interactive = Boolean(argv.i || argv.interactive);
|
|
123
119
|
const workspaceMode = Boolean(argv.workspace);
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
// Get specific modules from positional arguments (argv._)
|
|
121
|
+
const specificModules = argv._ && argv._.length > 0
|
|
122
|
+
? argv._.map((m) => String(m).trim())
|
|
126
123
|
: undefined;
|
|
127
124
|
const project = new PgpmPackage(cwd);
|
|
128
125
|
if (workspaceMode) {
|
|
@@ -138,7 +135,7 @@ export default async (argv, prompter, _options) => {
|
|
|
138
135
|
let anyUpgraded = false;
|
|
139
136
|
for (const moduleProject of modules) {
|
|
140
137
|
const moduleName = moduleProject.getModuleName();
|
|
141
|
-
const upgraded = await upgradeModulesForProject(moduleProject, argv, prompter, dryRun,
|
|
138
|
+
const upgraded = await upgradeModulesForProject(moduleProject, argv, prompter, dryRun, interactive, specificModules, moduleName);
|
|
142
139
|
if (upgraded) {
|
|
143
140
|
anyUpgraded = true;
|
|
144
141
|
}
|
|
@@ -152,6 +149,6 @@ export default async (argv, prompter, _options) => {
|
|
|
152
149
|
if (!project.isInModule()) {
|
|
153
150
|
throw new Error('You must run this command inside a PGPM module. Use --workspace to upgrade all modules in the workspace.');
|
|
154
151
|
}
|
|
155
|
-
await upgradeModulesForProject(project, argv, prompter, dryRun,
|
|
152
|
+
await upgradeModulesForProject(project, argv, prompter, dryRun, interactive, specificModules);
|
|
156
153
|
}
|
|
157
154
|
};
|
package/esm/commands.js
CHANGED
|
@@ -18,7 +18,7 @@ import migrate from './commands/migrate';
|
|
|
18
18
|
import _package from './commands/package';
|
|
19
19
|
import plan from './commands/plan';
|
|
20
20
|
import updateCmd from './commands/update';
|
|
21
|
-
import
|
|
21
|
+
import upgrade from './commands/upgrade';
|
|
22
22
|
import remove from './commands/remove';
|
|
23
23
|
import renameCmd from './commands/rename';
|
|
24
24
|
import revert from './commands/revert';
|
|
@@ -60,7 +60,8 @@ export const createPgpmCommandMap = (skipPgTeardown = false) => {
|
|
|
60
60
|
analyze: pgt(analyze),
|
|
61
61
|
rename: pgt(renameCmd),
|
|
62
62
|
'test-packages': pgt(testPackages),
|
|
63
|
-
|
|
63
|
+
upgrade: pgt(upgrade),
|
|
64
|
+
up: pgt(upgrade),
|
|
64
65
|
cache,
|
|
65
66
|
update: updateCmd
|
|
66
67
|
};
|
package/esm/utils/display.js
CHANGED
|
@@ -15,7 +15,7 @@ export const usageText = `
|
|
|
15
15
|
export Export database migrations from existing databases
|
|
16
16
|
update Update pgpm to the latest version
|
|
17
17
|
cache Manage cached templates (clean)
|
|
18
|
-
upgrade
|
|
18
|
+
upgrade Upgrade installed pgpm modules to latest versions (alias: up)
|
|
19
19
|
|
|
20
20
|
Database Administration:
|
|
21
21
|
kill Terminate database connections and optionally drop databases
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pgpm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "PostgreSQL Package Manager - Database migration and package management CLI",
|
|
6
6
|
"main": "index.js",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"test:watch": "jest --watch"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"@inquirerer/test": "^1.2.0",
|
|
36
37
|
"@types/js-yaml": "^4.0.9",
|
|
37
38
|
"@types/minimist": "^1.2.5",
|
|
38
39
|
"@types/node": "^20.12.7",
|
|
39
40
|
"@types/pg": "^8.16.0",
|
|
40
41
|
"@types/semver": "^7.5.8",
|
|
41
42
|
"@types/shelljs": "^0.8.16",
|
|
42
|
-
"clean-ansi": "0.1.5",
|
|
43
43
|
"glob": "^13.0.0",
|
|
44
44
|
"makage": "^0.1.9",
|
|
45
45
|
"pg": "^8.16.3",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@inquirerer/utils": "^3.1.1",
|
|
50
|
-
"@pgpmjs/core": "^4.
|
|
50
|
+
"@pgpmjs/core": "^4.5.0",
|
|
51
51
|
"@pgpmjs/env": "^2.8.11",
|
|
52
52
|
"@pgpmjs/logger": "^1.3.5",
|
|
53
53
|
"@pgpmjs/types": "^2.12.8",
|
|
54
54
|
"appstash": "^0.2.6",
|
|
55
55
|
"find-and-require-package-json": "^0.8.2",
|
|
56
|
-
"genomic": "^5.0
|
|
57
|
-
"inquirerer": "^4.
|
|
56
|
+
"genomic": "^5.2.0",
|
|
57
|
+
"inquirerer": "^4.2.0",
|
|
58
58
|
"js-yaml": "^4.1.0",
|
|
59
59
|
"minimist": "^1.2.8",
|
|
60
60
|
"pg-cache": "^1.6.11",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"pg",
|
|
76
76
|
"pgsql"
|
|
77
77
|
],
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "09721f934b339bd8c55d2e633abaded6d20b0f65"
|
|
79
79
|
}
|
package/utils/display.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const usageText = "\n Usage: pgpm <command> [options]\n\n Core Database Operations:\n add Add database changes to plans and create SQL files\n deploy Deploy database changes and migrations\n verify Verify database state and migrations\n revert Revert database changes and migrations\n\n Project Management:\n init Initialize workspace or module\n extension Manage module dependencies\n plan Generate module deployment plans\n package Package module for distribution\n export Export database migrations from existing databases\n update Update pgpm to the latest version\n cache Manage cached templates (clean)\n upgrade
|
|
1
|
+
export declare const usageText = "\n Usage: pgpm <command> [options]\n\n Core Database Operations:\n add Add database changes to plans and create SQL files\n deploy Deploy database changes and migrations\n verify Verify database state and migrations\n revert Revert database changes and migrations\n\n Project Management:\n init Initialize workspace or module\n extension Manage module dependencies\n plan Generate module deployment plans\n package Package module for distribution\n export Export database migrations from existing databases\n update Update pgpm to the latest version\n cache Manage cached templates (clean)\n upgrade Upgrade installed pgpm modules to latest versions (alias: up)\n\n Database Administration:\n kill Terminate database connections and optionally drop databases\n install Install database modules\n tag Add tags to changes for versioning\n clear Clear database state\n remove Remove database changes\n analyze Analyze database structure\n rename Rename database changes\n admin-users Manage admin users\n\n Testing:\n test-packages Run integration tests on all workspace packages\n\n Migration Tools:\n migrate Migration management subcommands\n init Initialize migration tracking\n status Show migration status\n list List all changes\n deps Show change dependencies\n \n Development Tools:\n docker Manage PostgreSQL Docker containers (start/stop)\n env Manage PostgreSQL environment variables\n test-packages Run integration tests on workspace packages\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 pgpm <command> --help Display detailed help for specific command\n pgpm <command> -h Display detailed help for specific command\n\n Examples:\n pgpm deploy --help Show deploy command options\n pgpm init workspace Initialize new workspace\n pgpm install @pgpm/base32 Install a database module\n ";
|
package/utils/display.js
CHANGED
|
@@ -18,7 +18,7 @@ exports.usageText = `
|
|
|
18
18
|
export Export database migrations from existing databases
|
|
19
19
|
update Update pgpm to the latest version
|
|
20
20
|
cache Manage cached templates (clean)
|
|
21
|
-
upgrade
|
|
21
|
+
upgrade Upgrade installed pgpm modules to latest versions (alias: up)
|
|
22
22
|
|
|
23
23
|
Database Administration:
|
|
24
24
|
kill Terminate database connections and optionally drop databases
|
|
File without changes
|