pgpm 2.2.1 → 2.4.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.
@@ -42,39 +42,35 @@ exports.default = async (argv, prompter, _options) => {
42
42
  WHERE datistemplate = FALSE AND datname NOT IN ('postgres')
43
43
  AND datname !~ '^pg_';
44
44
  `);
45
- let databases;
46
- ({ databases } = await prompter.prompt(argv, [
45
+ const { databases: dbname } = await prompter.prompt(argv, [
47
46
  {
48
- type: 'checkbox',
47
+ type: 'list',
49
48
  name: 'databases',
50
49
  message: 'Select a database',
51
50
  options: databasesResult.rows.map(row => row.datname),
52
51
  required: true
53
52
  }
54
- ]));
55
- const dbname = databases.filter(d => d.selected).map(d => d.value)[0];
53
+ ]);
56
54
  const selectedDb = await (0, pg_cache_1.getPgPool)({
57
55
  database: dbname
58
56
  });
59
57
  const dbsResult = await selectedDb.query(`
60
58
  SELECT id, name FROM collections_public.database;
61
59
  `);
62
- let database_ids;
63
- ({ database_ids } = await prompter.prompt({}, [
60
+ const { database_ids: selectedDatabaseName } = await prompter.prompt({}, [
64
61
  {
65
- type: 'checkbox',
62
+ type: 'list',
66
63
  name: 'database_ids',
67
- message: 'Select database_id(s)',
64
+ message: 'Select database_id',
68
65
  options: dbsResult.rows.map(db => db.name),
69
66
  required: true
70
67
  }
71
- ]));
72
- const selectedDatabaseNames = database_ids
73
- .filter(did => did.selected)
74
- .map(did => did.name);
68
+ ]);
69
+ const selectedDatabase = dbsResult.rows.find(db => db.name === selectedDatabaseName);
75
70
  const dbInfo = {
76
71
  dbname,
77
- database_ids: database_ids.map(did => dbsResult.rows.find(db => db.name === did.name).id)
72
+ databaseName: selectedDatabaseName,
73
+ database_ids: [selectedDatabase.id]
78
74
  };
79
75
  const { author, extensionName, metaExtensionName } = await prompter.prompt(argv, [
80
76
  {
@@ -88,14 +84,14 @@ exports.default = async (argv, prompter, _options) => {
88
84
  type: 'text',
89
85
  name: 'extensionName',
90
86
  message: 'Extension name',
91
- default: selectedDatabaseNames[0] || dbname,
87
+ default: selectedDatabaseName || dbname,
92
88
  required: true
93
89
  },
94
90
  {
95
91
  type: 'text',
96
92
  name: 'metaExtensionName',
97
93
  message: 'Meta extension name',
98
- default: 'svc',
94
+ default: `${selectedDatabaseName || dbname}-service`,
99
95
  required: true
100
96
  }
101
97
  ]);
@@ -111,7 +107,6 @@ exports.default = async (argv, prompter, _options) => {
111
107
  }
112
108
  ]);
113
109
  const outdir = (0, path_1.resolve)(project.workspacePath, 'packages/');
114
- prompter.close();
115
110
  await (0, core_1.exportMigrations)({
116
111
  project,
117
112
  options,
@@ -120,8 +115,10 @@ exports.default = async (argv, prompter, _options) => {
120
115
  schema_names,
121
116
  outdir,
122
117
  extensionName,
123
- metaExtensionName
118
+ metaExtensionName,
119
+ prompter
124
120
  });
121
+ prompter.close();
125
122
  console.log(`
126
123
 
127
124
  |||
@@ -74,6 +74,8 @@ async function handleInit(argv, prompter) {
74
74
  }
75
75
  // Regular init path: default to 'module' if no fromPath provided
76
76
  const fromPath = positionalFromPath || 'module';
77
+ // Track if user explicitly requested module (e.g., `pgpm init module`)
78
+ const wasExplicitModuleRequest = positionalFromPath === 'module';
77
79
  // Inspect the template to get its type
78
80
  const inspection = (0, core_1.inspectTemplate)({
79
81
  fromPath,
@@ -103,7 +105,7 @@ async function handleInit(argv, prompter) {
103
105
  dir,
104
106
  noTty,
105
107
  cwd,
106
- });
108
+ }, wasExplicitModuleRequest);
107
109
  }
108
110
  async function handleBoilerplateInit(argv, prompter, ctx) {
109
111
  let fromPath;
@@ -171,6 +173,7 @@ async function handleBoilerplateInit(argv, prompter, ctx) {
171
173
  });
172
174
  }
173
175
  // Default to module init (for 'module' type or unknown types)
176
+ // When using --boilerplate, user made an explicit choice, so treat as explicit request
174
177
  return handleModuleInit(argv, prompter, {
175
178
  fromPath,
176
179
  templateRepo: ctx.templateRepo,
@@ -178,7 +181,7 @@ async function handleBoilerplateInit(argv, prompter, ctx) {
178
181
  dir: ctx.dir,
179
182
  noTty: ctx.noTty,
180
183
  cwd: ctx.cwd,
181
- });
184
+ }, true);
182
185
  }
183
186
  async function handleWorkspaceInit(argv, prompter, ctx) {
184
187
  const workspaceQuestions = [
@@ -229,9 +232,37 @@ async function handleWorkspaceInit(argv, prompter, ctx) {
229
232
  process.stdout.write(`\n✨ Enjoy!\n\ncd ./${dirName}\n`);
230
233
  return { ...argv, ...answers, cwd: targetPath };
231
234
  }
232
- async function handleModuleInit(argv, prompter, ctx) {
235
+ async function handleModuleInit(argv, prompter, ctx, wasExplicitModuleRequest = false) {
233
236
  const project = new core_1.PgpmPackage(ctx.cwd);
234
237
  if (!project.workspacePath) {
238
+ const noTty = Boolean(argv.noTty || argv['no-tty'] || process.env.CI === 'true');
239
+ // If user explicitly requested module init or we're in non-interactive mode,
240
+ // just show the error with helpful guidance
241
+ if (wasExplicitModuleRequest || noTty) {
242
+ process.stderr.write('Not inside a PGPM workspace.\n');
243
+ throw types_1.errors.NOT_IN_WORKSPACE({});
244
+ }
245
+ // Offer to create a workspace instead
246
+ const recoveryQuestion = [
247
+ {
248
+ name: 'createWorkspace',
249
+ message: 'You are not inside a PGPM workspace. Would you like to create a new workspace instead?',
250
+ type: 'confirm',
251
+ required: true,
252
+ },
253
+ ];
254
+ const { createWorkspace } = await prompter.prompt(argv, recoveryQuestion);
255
+ if (createWorkspace) {
256
+ return handleWorkspaceInit(argv, prompter, {
257
+ fromPath: 'workspace',
258
+ templateRepo: ctx.templateRepo,
259
+ branch: ctx.branch,
260
+ dir: ctx.dir,
261
+ noTty: ctx.noTty,
262
+ cwd: ctx.cwd,
263
+ });
264
+ }
265
+ // User declined, show the error
235
266
  process.stderr.write('Not inside a PGPM workspace.\n');
236
267
  throw types_1.errors.NOT_IN_WORKSPACE({});
237
268
  }
@@ -40,39 +40,35 @@ export default async (argv, prompter, _options) => {
40
40
  WHERE datistemplate = FALSE AND datname NOT IN ('postgres')
41
41
  AND datname !~ '^pg_';
42
42
  `);
43
- let databases;
44
- ({ databases } = await prompter.prompt(argv, [
43
+ const { databases: dbname } = await prompter.prompt(argv, [
45
44
  {
46
- type: 'checkbox',
45
+ type: 'list',
47
46
  name: 'databases',
48
47
  message: 'Select a database',
49
48
  options: databasesResult.rows.map(row => row.datname),
50
49
  required: true
51
50
  }
52
- ]));
53
- const dbname = databases.filter(d => d.selected).map(d => d.value)[0];
51
+ ]);
54
52
  const selectedDb = await getPgPool({
55
53
  database: dbname
56
54
  });
57
55
  const dbsResult = await selectedDb.query(`
58
56
  SELECT id, name FROM collections_public.database;
59
57
  `);
60
- let database_ids;
61
- ({ database_ids } = await prompter.prompt({}, [
58
+ const { database_ids: selectedDatabaseName } = await prompter.prompt({}, [
62
59
  {
63
- type: 'checkbox',
60
+ type: 'list',
64
61
  name: 'database_ids',
65
- message: 'Select database_id(s)',
62
+ message: 'Select database_id',
66
63
  options: dbsResult.rows.map(db => db.name),
67
64
  required: true
68
65
  }
69
- ]));
70
- const selectedDatabaseNames = database_ids
71
- .filter(did => did.selected)
72
- .map(did => did.name);
66
+ ]);
67
+ const selectedDatabase = dbsResult.rows.find(db => db.name === selectedDatabaseName);
73
68
  const dbInfo = {
74
69
  dbname,
75
- database_ids: database_ids.map(did => dbsResult.rows.find(db => db.name === did.name).id)
70
+ databaseName: selectedDatabaseName,
71
+ database_ids: [selectedDatabase.id]
76
72
  };
77
73
  const { author, extensionName, metaExtensionName } = await prompter.prompt(argv, [
78
74
  {
@@ -86,14 +82,14 @@ export default async (argv, prompter, _options) => {
86
82
  type: 'text',
87
83
  name: 'extensionName',
88
84
  message: 'Extension name',
89
- default: selectedDatabaseNames[0] || dbname,
85
+ default: selectedDatabaseName || dbname,
90
86
  required: true
91
87
  },
92
88
  {
93
89
  type: 'text',
94
90
  name: 'metaExtensionName',
95
91
  message: 'Meta extension name',
96
- default: 'svc',
92
+ default: `${selectedDatabaseName || dbname}-service`,
97
93
  required: true
98
94
  }
99
95
  ]);
@@ -109,7 +105,6 @@ export default async (argv, prompter, _options) => {
109
105
  }
110
106
  ]);
111
107
  const outdir = resolve(project.workspacePath, 'packages/');
112
- prompter.close();
113
108
  await exportMigrations({
114
109
  project,
115
110
  options,
@@ -118,8 +113,10 @@ export default async (argv, prompter, _options) => {
118
113
  schema_names,
119
114
  outdir,
120
115
  extensionName,
121
- metaExtensionName
116
+ metaExtensionName,
117
+ prompter
122
118
  });
119
+ prompter.close();
123
120
  console.log(`
124
121
 
125
122
  |||
@@ -67,6 +67,8 @@ async function handleInit(argv, prompter) {
67
67
  }
68
68
  // Regular init path: default to 'module' if no fromPath provided
69
69
  const fromPath = positionalFromPath || 'module';
70
+ // Track if user explicitly requested module (e.g., `pgpm init module`)
71
+ const wasExplicitModuleRequest = positionalFromPath === 'module';
70
72
  // Inspect the template to get its type
71
73
  const inspection = inspectTemplate({
72
74
  fromPath,
@@ -96,7 +98,7 @@ async function handleInit(argv, prompter) {
96
98
  dir,
97
99
  noTty,
98
100
  cwd,
99
- });
101
+ }, wasExplicitModuleRequest);
100
102
  }
101
103
  async function handleBoilerplateInit(argv, prompter, ctx) {
102
104
  let fromPath;
@@ -164,6 +166,7 @@ async function handleBoilerplateInit(argv, prompter, ctx) {
164
166
  });
165
167
  }
166
168
  // Default to module init (for 'module' type or unknown types)
169
+ // When using --boilerplate, user made an explicit choice, so treat as explicit request
167
170
  return handleModuleInit(argv, prompter, {
168
171
  fromPath,
169
172
  templateRepo: ctx.templateRepo,
@@ -171,7 +174,7 @@ async function handleBoilerplateInit(argv, prompter, ctx) {
171
174
  dir: ctx.dir,
172
175
  noTty: ctx.noTty,
173
176
  cwd: ctx.cwd,
174
- });
177
+ }, true);
175
178
  }
176
179
  async function handleWorkspaceInit(argv, prompter, ctx) {
177
180
  const workspaceQuestions = [
@@ -222,9 +225,37 @@ async function handleWorkspaceInit(argv, prompter, ctx) {
222
225
  process.stdout.write(`\n✨ Enjoy!\n\ncd ./${dirName}\n`);
223
226
  return { ...argv, ...answers, cwd: targetPath };
224
227
  }
225
- async function handleModuleInit(argv, prompter, ctx) {
228
+ async function handleModuleInit(argv, prompter, ctx, wasExplicitModuleRequest = false) {
226
229
  const project = new PgpmPackage(ctx.cwd);
227
230
  if (!project.workspacePath) {
231
+ const noTty = Boolean(argv.noTty || argv['no-tty'] || process.env.CI === 'true');
232
+ // If user explicitly requested module init or we're in non-interactive mode,
233
+ // just show the error with helpful guidance
234
+ if (wasExplicitModuleRequest || noTty) {
235
+ process.stderr.write('Not inside a PGPM workspace.\n');
236
+ throw errors.NOT_IN_WORKSPACE({});
237
+ }
238
+ // Offer to create a workspace instead
239
+ const recoveryQuestion = [
240
+ {
241
+ name: 'createWorkspace',
242
+ message: 'You are not inside a PGPM workspace. Would you like to create a new workspace instead?',
243
+ type: 'confirm',
244
+ required: true,
245
+ },
246
+ ];
247
+ const { createWorkspace } = await prompter.prompt(argv, recoveryQuestion);
248
+ if (createWorkspace) {
249
+ return handleWorkspaceInit(argv, prompter, {
250
+ fromPath: 'workspace',
251
+ templateRepo: ctx.templateRepo,
252
+ branch: ctx.branch,
253
+ dir: ctx.dir,
254
+ noTty: ctx.noTty,
255
+ cwd: ctx.cwd,
256
+ });
257
+ }
258
+ // User declined, show the error
228
259
  process.stderr.write('Not inside a PGPM workspace.\n');
229
260
  throw errors.NOT_IN_WORKSPACE({});
230
261
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgpm",
3
- "version": "2.2.1",
3
+ "version": "2.4.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",
@@ -39,23 +39,24 @@
39
39
  "@types/pg": "^8.16.0",
40
40
  "@types/semver": "^7.5.8",
41
41
  "@types/shelljs": "^0.8.16",
42
+ "clean-ansi": "0.1.5",
42
43
  "glob": "^13.0.0",
43
44
  "makage": "^0.1.9",
44
45
  "pg": "^8.16.3",
45
46
  "ts-node": "^10.9.2"
46
47
  },
47
48
  "dependencies": {
48
- "@pgpmjs/core": "^4.1.1",
49
- "@pgpmjs/env": "^2.8.10",
49
+ "@pgpmjs/core": "^4.2.0",
50
+ "@pgpmjs/env": "^2.8.11",
50
51
  "@pgpmjs/logger": "^1.3.5",
51
- "@pgpmjs/types": "^2.12.7",
52
+ "@pgpmjs/types": "^2.12.8",
52
53
  "appstash": "^0.2.6",
53
54
  "create-gen-app": "^0.10.0",
54
55
  "find-and-require-package-json": "^0.8.2",
55
56
  "inquirerer": "^2.4.0",
56
57
  "js-yaml": "^4.1.0",
57
58
  "minimist": "^1.2.8",
58
- "pg-cache": "^1.6.10",
59
+ "pg-cache": "^1.6.11",
59
60
  "pg-env": "^1.2.4",
60
61
  "semver": "^7.6.2",
61
62
  "shelljs": "^0.10.0",
@@ -73,5 +74,5 @@
73
74
  "pg",
74
75
  "pgsql"
75
76
  ],
76
- "gitHead": "e3d01915223e3d87d263606bc4086e3e88183cab"
77
+ "gitHead": "9b68e2d19937ad4e2a81a5de110a197a8572e3d9"
77
78
  }