pgpm 0.2.17 โ†’ 0.3.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/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
3
  Copyright (c) 2025 Dan Lynch <pyramation@gmail.com>
4
- Copyright (c) 2025 Hyperweb <developers@hyperweb.io>
4
+ Copyright (c) 2025 Constructive <developers@constructive.io>
5
5
  Copyright (c) 2020-present, Interweb, Inc.
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
package/README.md CHANGED
@@ -34,7 +34,7 @@ eval "$(pgpm env)"
34
34
 
35
35
  ```bash
36
36
  # 1. Create a workspace
37
- pgpm init --workspace
37
+ pgpm init workspace
38
38
  cd my-app
39
39
 
40
40
  # 2. Create your first module
@@ -55,7 +55,7 @@ psql -d mydb1 -c "SELECT faker.city('MI');"
55
55
  ### Getting Started
56
56
 
57
57
  - `pgpm init` - Initialize a new module
58
- - `pgpm init --workspace` - Initialize a new workspace
58
+ - `pgpm init workspace` - Initialize a new workspace
59
59
 
60
60
  ### Development Setup
61
61
 
@@ -98,6 +98,8 @@ psql -d mydb1 -c "SELECT faker.city('MI');"
98
98
  - `pgpm analyze` - Analyze database structure
99
99
  - `pgpm rename` - Rename database changes
100
100
  - `pgpm admin-users` - Manage admin users
101
+ - `pgpm cache clean` - Clear cached template repos used by `pgpm init`
102
+ - `pgpm update` - Install the latest pgpm version from npm
101
103
 
102
104
  ## ๐Ÿ’ก Common Workflows
103
105
 
@@ -105,7 +107,7 @@ psql -d mydb1 -c "SELECT faker.city('MI');"
105
107
 
106
108
  ```bash
107
109
  # 1. Create workspace
108
- pgpm init --workspace
110
+ pgpm init workspace
109
111
  cd my-app
110
112
 
111
113
  # 2. Create your first module
@@ -119,6 +121,12 @@ pgpm add some_change
119
121
  pgpm deploy --createdb
120
122
  ```
121
123
 
124
+ ## ๐Ÿงฐ Templates, Caching, and Updates
125
+
126
+ - `pgpm init` now scaffolds workspaces/modules from `https://github.com/launchql/pgpm-boilerplates.git` using `create-gen-app` with a one-week cache (stored under `~/.pgpm/cache/repos`). Override with `--repo`, `--from-branch`, and `--template-path`, or use a local template path.
127
+ - Run `pgpm cache clean` to wipe the cached boilerplates if you need a fresh pull.
128
+ - The CLI performs a lightweight npm version check at most once per week (skipped in CI or when `PGPM_SKIP_UPDATE_CHECK` is set). Use `pgpm update` to upgrade to the latest release.
129
+
122
130
  ### Working with Existing Projects
123
131
 
124
132
  ```bash
@@ -342,71 +350,71 @@ Most commands support these global options:
342
350
 
343
351
  ## Education and Tutorials
344
352
 
345
- 1. ๐Ÿš€ [Quickstart: Getting Up and Running](https://launchql.com/learn/quickstart)
353
+ 1. ๐Ÿš€ [Quickstart: Getting Up and Running](https://constructive.io/learn/quickstart)
346
354
  Get started with modular databases in minutes. Install prerequisites and deploy your first module.
347
355
 
348
- 2. ๐Ÿ“ฆ [Modular PostgreSQL Development with Database Packages](https://launchql.com/learn/modular-postgres)
356
+ 2. ๐Ÿ“ฆ [Modular PostgreSQL Development with Database Packages](https://constructive.io/learn/modular-postgres)
349
357
  Learn to organize PostgreSQL projects with pgpm workspaces and reusable database modules.
350
358
 
351
- 3. โœ๏ธ [Authoring Database Changes](https://launchql.com/learn/authoring-database-changes)
359
+ 3. โœ๏ธ [Authoring Database Changes](https://constructive.io/learn/authoring-database-changes)
352
360
  Master the workflow for adding, organizing, and managing database changes with pgpm.
353
361
 
354
- 4. ๐Ÿงช [End-to-End PostgreSQL Testing with TypeScript](https://launchql.com/learn/e2e-postgres-testing)
362
+ 4. ๐Ÿงช [End-to-End PostgreSQL Testing with TypeScript](https://constructive.io/learn/e2e-postgres-testing)
355
363
  Master end-to-end PostgreSQL testing with ephemeral databases, RLS testing, and CI/CD automation.
356
364
 
357
- 5. โšก [Supabase Testing](https://launchql.com/learn/supabase)
365
+ 5. โšก [Supabase Testing](https://constructive.io/learn/supabase)
358
366
  Use TypeScript-first tools to test Supabase projects with realistic RLS, policies, and auth contexts.
359
367
 
360
- 6. ๐Ÿ’ง [Drizzle ORM Testing](https://launchql.com/learn/drizzle-testing)
368
+ 6. ๐Ÿ’ง [Drizzle ORM Testing](https://constructive.io/learn/drizzle-testing)
361
369
  Run full-stack tests with Drizzle ORM, including database setup, teardown, and RLS enforcement.
362
370
 
363
- 7. ๐Ÿ”ง [Troubleshooting](https://launchql.com/learn/troubleshooting)
371
+ 7. ๐Ÿ”ง [Troubleshooting](https://constructive.io/learn/troubleshooting)
364
372
  Common issues and solutions for pgpm, PostgreSQL, and testing.
365
373
 
366
- ## Related LaunchQL Tooling
374
+ ## Related Constructive Tooling
367
375
 
368
376
  ### ๐Ÿงช Testing
369
377
 
370
- * [launchql/pgsql-test](https://github.com/launchql/launchql/tree/main/packages/pgsql-test): **๐Ÿ“Š Isolated testing environments** with per-test transaction rollbacksโ€”ideal for integration tests, complex migrations, and RLS simulation.
371
- * [launchql/supabase-test](https://github.com/launchql/launchql/tree/main/packages/supabase-test): **๐Ÿงช Supabase-native test harness** preconfigured for the local Supabase stackโ€”per-test rollbacks, JWT/role context helpers, and CI/GitHub Actions ready.
372
- * [launchql/graphile-test](https://github.com/launchql/launchql/tree/main/packages/graphile-test): **๐Ÿ” Authentication mocking** for Graphile-focused test helpers and emulating row-level security contexts.
373
- * [launchql/pg-query-context](https://github.com/launchql/launchql/tree/main/packages/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.
378
+ * [pgsql-test](https://github.com/constructive-io/constructive/tree/main/packages/pgsql-test): **๐Ÿ“Š Isolated testing environments** with per-test transaction rollbacksโ€”ideal for integration tests, complex migrations, and RLS simulation.
379
+ * [supabase-test](https://github.com/constructive-io/constructive/tree/main/packages/supabase-test): **๐Ÿงช Supabase-native test harness** preconfigured for the local Supabase stackโ€”per-test rollbacks, JWT/role context helpers, and CI/GitHub Actions ready.
380
+ * [graphile-test](https://github.com/constructive-io/constructive/tree/main/packages/graphile-test): **๐Ÿ” Authentication mocking** for Graphile-focused test helpers and emulating row-level security contexts.
381
+ * [pg-query-context](https://github.com/constructive-io/constructive/tree/main/packages/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.
374
382
 
375
383
  ### ๐Ÿง  Parsing & AST
376
384
 
377
- * [launchql/pgsql-parser](https://github.com/launchql/pgsql-parser): **๐Ÿ”„ SQL conversion engine** that interprets and converts PostgreSQL syntax.
378
- * [launchql/libpg-query-node](https://github.com/launchql/libpg-query-node): **๐ŸŒ‰ Node.js bindings** for `libpg_query`, converting SQL into parse trees.
379
- * [launchql/pg-proto-parser](https://github.com/launchql/pg-proto-parser): **๐Ÿ“ฆ Protobuf parser** for parsing PostgreSQL Protocol Buffers definitions to generate TypeScript interfaces, utility functions, and JSON mappings for enums.
380
- * [@pgsql/enums](https://github.com/launchql/pgsql-parser/tree/main/packages/enums): **๐Ÿท๏ธ TypeScript enums** for PostgreSQL AST for safe and ergonomic parsing logic.
381
- * [@pgsql/types](https://github.com/launchql/pgsql-parser/tree/main/packages/types): **๐Ÿ“ Type definitions** for PostgreSQL AST nodes in TypeScript.
382
- * [@pgsql/utils](https://github.com/launchql/pgsql-parser/tree/main/packages/utils): **๐Ÿ› ๏ธ AST utilities** for constructing and transforming PostgreSQL syntax trees.
383
- * [launchql/pg-ast](https://github.com/launchql/launchql/tree/main/packages/pg-ast): **๐Ÿ” Low-level AST tools** and transformations for Postgres query structures.
385
+ * [pgsql-parser](https://www.npmjs.com/package/pgsql-parser): **๐Ÿ”„ SQL conversion engine** that interprets and converts PostgreSQL syntax.
386
+ * [libpg-query-node](https://www.npmjs.com/package/libpg-query): **๐ŸŒ‰ Node.js bindings** for `libpg_query`, converting SQL into parse trees.
387
+ * [pg-proto-parser](https://www.npmjs.com/package/pg-proto-parser): **๐Ÿ“ฆ Protobuf parser** for parsing PostgreSQL Protocol Buffers definitions to generate TypeScript interfaces, utility functions, and JSON mappings for enums.
388
+ * [@pgsql/enums](https://www.npmjs.com/package/@pgsql/enums): **๐Ÿท๏ธ TypeScript enums** for PostgreSQL AST for safe and ergonomic parsing logic.
389
+ * [@pgsql/types](https://www.npmjs.com/package/@pgsql/types): **๐Ÿ“ Type definitions** for PostgreSQL AST nodes in TypeScript.
390
+ * [@pgsql/utils](https://www.npmjs.com/package/@pgsql/utils): **๐Ÿ› ๏ธ AST utilities** for constructing and transforming PostgreSQL syntax trees.
391
+ * [pg-ast](https://www.npmjs.com/package/pg-ast): **๐Ÿ” Low-level AST tools** and transformations for Postgres query structures.
384
392
 
385
393
  ### ๐Ÿš€ API & Dev Tools
386
394
 
387
- * [launchql/server](https://github.com/launchql/launchql/tree/main/packages/server): **โšก Express-based API server** powered by PostGraphile to expose a secure, scalable GraphQL API over your Postgres database.
388
- * [launchql/explorer](https://github.com/launchql/launchql/tree/main/packages/explorer): **๐Ÿ”Ž Visual API explorer** with GraphiQL for browsing across all databases and schemasโ€”useful for debugging, documentation, and API prototyping.
395
+ * [launchql/server](https://github.com/constructive-io/constructive/tree/main/packages/server): **โšก Express-based API server** powered by PostGraphile to expose a secure, scalable GraphQL API over your Postgres database.
396
+ * [launchql/explorer](https://github.com/constructive-io/constructive/tree/main/packages/explorer): **๐Ÿ”Ž Visual API explorer** with GraphiQL for browsing across all databases and schemasโ€”useful for debugging, documentation, and API prototyping.
389
397
 
390
398
  ### ๐Ÿ” Streaming & Uploads
391
399
 
392
- * [launchql/s3-streamer](https://github.com/launchql/launchql/tree/main/packages/s3-streamer): **๐Ÿ“ค Direct S3 streaming** for large files with support for metadata injection and content validation.
393
- * [launchql/etag-hash](https://github.com/launchql/launchql/tree/main/packages/etag-hash): **๐Ÿท๏ธ S3-compatible ETags** created by streaming and hashing file uploads in chunks.
394
- * [launchql/etag-stream](https://github.com/launchql/launchql/tree/main/packages/etag-stream): **๐Ÿ”„ ETag computation** via Node stream transformer during upload or transfer.
395
- * [launchql/uuid-hash](https://github.com/launchql/launchql/tree/main/packages/uuid-hash): **๐Ÿ†” Deterministic UUIDs** generated from hashed content, great for deduplication and asset referencing.
396
- * [launchql/uuid-stream](https://github.com/launchql/launchql/tree/main/packages/uuid-stream): **๐ŸŒŠ Streaming UUID generation** based on piped file contentโ€”ideal for upload pipelines.
397
- * [launchql/upload-names](https://github.com/launchql/launchql/tree/main/packages/upload-names): **๐Ÿ“‚ Collision-resistant filenames** utility for structured and unique file names for uploads.
400
+ * [launchql/s3-streamer](https://github.com/constructive-io/constructive/tree/main/packages/s3-streamer): **๐Ÿ“ค Direct S3 streaming** for large files with support for metadata injection and content validation.
401
+ * [launchql/etag-hash](https://github.com/constructive-io/constructive/tree/main/packages/etag-hash): **๐Ÿท๏ธ S3-compatible ETags** created by streaming and hashing file uploads in chunks.
402
+ * [launchql/etag-stream](https://github.com/constructive-io/constructive/tree/main/packages/etag-stream): **๐Ÿ”„ ETag computation** via Node stream transformer during upload or transfer.
403
+ * [launchql/uuid-hash](https://github.com/constructive-io/constructive/tree/main/packages/uuid-hash): **๐Ÿ†” Deterministic UUIDs** generated from hashed content, great for deduplication and asset referencing.
404
+ * [launchql/uuid-stream](https://github.com/constructive-io/constructive/tree/main/packages/uuid-stream): **๐ŸŒŠ Streaming UUID generation** based on piped file contentโ€”ideal for upload pipelines.
405
+ * [launchql/upload-names](https://github.com/constructive-io/constructive/tree/main/packages/upload-names): **๐Ÿ“‚ Collision-resistant filenames** utility for structured and unique file names for uploads.
398
406
 
399
407
  ### ๐Ÿงฐ CLI & Codegen
400
408
 
401
- * [pgpm](https://github.com/launchql/launchql/tree/main/packages/pgpm): **๐Ÿ–ฅ๏ธ PostgreSQL Package Manager** for modular Postgres development. Works with database workspaces, scaffolding, migrations, seeding, and installing database packages.
402
- * [@launchql/cli](https://github.com/launchql/launchql/tree/main/packages/cli): **๐Ÿ–ฅ๏ธ Command-line toolkit** for managing LaunchQL projectsโ€”supports database scaffolding, migrations, seeding, code generation, and automation.
403
- * [launchql/launchql-gen](https://github.com/launchql/launchql/tree/main/packages/launchql-gen): **โœจ Auto-generated GraphQL** mutations and queries dynamically built from introspected schema data.
404
- * [@launchql/query-builder](https://github.com/launchql/launchql/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.
405
- * [@launchql/query](https://github.com/launchql/launchql/tree/main/packages/query): **๐Ÿงฉ Fluent GraphQL builder** for PostGraphile schemas. โšก Schema-aware via introspection, ๐Ÿงฉ composable and ergonomic for building deeply nested queries.
409
+ * [pgpm](https://github.com/constructive-io/constructive/tree/main/packages/pgpm): **๐Ÿ–ฅ๏ธ PostgreSQL Package Manager** for modular Postgres development. Works with database workspaces, scaffolding, migrations, seeding, and installing database packages.
410
+ * [@launchql/cli](https://github.com/constructive-io/constructive/tree/main/packages/cli): **๐Ÿ–ฅ๏ธ Command-line toolkit** for managing LaunchQL projectsโ€”supports database scaffolding, migrations, seeding, code generation, and automation.
411
+ * [constructive-io/constructive-gen](https://github.com/constructive-io/constructive/tree/main/packages/launchql-gen): **โœจ Auto-generated GraphQL** mutations and queries dynamically built from introspected schema data.
412
+ * [@launchql/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.
413
+ * [@launchql/query](https://github.com/constructive-io/constructive/tree/main/packages/query): **๐Ÿงฉ Fluent GraphQL builder** for PostGraphile schemas. โšก Schema-aware via introspection, ๐Ÿงฉ composable and ergonomic for building deeply nested queries.
406
414
 
407
415
  ## Credits
408
416
 
409
- ๐Ÿ›  Built by LaunchQL โ€”ย if you like our tools, please checkout and contribute to [our github โš›๏ธ](https://github.com/launchql)
417
+ ๐Ÿ›  Built by Constructive โ€”ย if you like our tools, please checkout and contribute to [our github โš›๏ธ](https://github.com/constructive-io)
410
418
 
411
419
 
412
420
  ## Disclaimer
@@ -0,0 +1,3 @@
1
+ import { CLIOptions, Inquirerer } from 'inquirerer';
2
+ declare const _default: (argv: Partial<Record<string, any>>, _prompter: Inquirerer, _options: CLIOptions) => Promise<Partial<Record<string, any>>>;
3
+ export default _default;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const logger_1 = require("@launchql/logger");
4
+ const create_gen_app_1 = require("create-gen-app");
5
+ const cli_error_1 = require("../utils/cli-error");
6
+ const log = new logger_1.Logger('cache');
7
+ const cacheUsageText = `
8
+ Cache Command:
9
+
10
+ pgpm cache clean [OPTIONS]
11
+
12
+ Options:
13
+ --help, -h Show this help message
14
+ --tool <name> Cache namespace to clear (default: pgpm)
15
+ `;
16
+ exports.default = async (argv, _prompter, _options) => {
17
+ if (argv.help || argv.h) {
18
+ console.log(cacheUsageText);
19
+ process.exit(0);
20
+ }
21
+ const action = argv._?.[0] || 'clean';
22
+ if (action !== 'clean') {
23
+ console.log(cacheUsageText);
24
+ await (0, cli_error_1.cliExitWithError)(`Unknown cache action: ${action}`);
25
+ }
26
+ const toolName = argv.tool || 'pgpm';
27
+ const cacheManager = new create_gen_app_1.CacheManager({ toolName });
28
+ cacheManager.clearAll();
29
+ log.success(`Cleared template cache for "${toolName}".`);
30
+ log.debug(`Cache location: ${cacheManager.getReposDir()}`);
31
+ return argv;
32
+ };
@@ -1,4 +1,5 @@
1
1
  import { CLIOptions, Inquirerer } from 'inquirerer';
2
+ export declare const createInitUsageText: (binaryName: string, productLabel?: string) => string;
2
3
  declare const _default: (argv: Partial<Record<string, any>>, prompter: Inquirerer, _options: CLIOptions) => Promise<{
3
4
  [x: string]: any;
4
5
  } | {
@@ -3,45 +3,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createInitUsageText = void 0;
6
7
  const module_1 = __importDefault(require("./module"));
7
8
  const workspace_1 = __importDefault(require("./workspace"));
8
- const initUsageText = `
9
+ const createInitUsageText = (binaryName, productLabel) => {
10
+ const displayName = productLabel ?? binaryName;
11
+ return `
9
12
  Init Command:
10
13
 
11
- pgpm init [OPTIONS]
14
+ ${binaryName} init [OPTIONS] [workspace]
12
15
 
13
- Initialize pgpm workspace or module.
16
+ Initialize ${displayName} workspace or module.
14
17
 
15
18
  Options:
16
19
  --help, -h Show this help message
17
- --workspace Initialize workspace instead of module
18
20
  --cwd <directory> Working directory (default: current directory)
19
- --repo <repo> Use templates from GitHub repository (e.g., owner/repo)
20
- --template-path <path> Use templates from local path
21
- --from-branch <branch> Specify branch when using --repo (default: main)
21
+ --repo <repo> Template repo (default: https://github.com/launchql/pgpm-boilerplates.git)
22
+ --template-path <path> Template sub-path (default: workspace/module) or local path override
23
+ --from-branch <branch> Branch/tag to use when cloning repo
22
24
 
23
25
  Examples:
24
- pgpm init Initialize new module in existing workspace
25
- pgpm init --workspace Initialize new workspace
26
- pgpm init --repo owner/repo Use templates from GitHub repository
27
- pgpm init --template-path ./custom-templates Use templates from local path
28
- pgpm init --repo owner/repo --from-branch develop Use specific branch
26
+ ${binaryName} init Initialize new module in existing workspace
27
+ ${binaryName} init workspace Initialize new workspace
28
+ ${binaryName} init --repo owner/repo Use templates from GitHub repository
29
+ ${binaryName} init --template-path ./custom-templates Use templates from local path
30
+ ${binaryName} init --repo owner/repo --from-branch develop Use specific branch
29
31
  `;
32
+ };
33
+ exports.createInitUsageText = createInitUsageText;
30
34
  exports.default = async (argv, prompter, _options) => {
31
35
  // Show usage if explicitly requested
32
36
  if (argv.help || argv.h) {
33
- console.log(initUsageText);
37
+ console.log((0, exports.createInitUsageText)('pgpm'));
34
38
  process.exit(0);
35
39
  }
36
40
  return handlePromptFlow(argv, prompter);
37
41
  };
38
42
  async function handlePromptFlow(argv, prompter) {
39
- const { workspace } = argv;
40
- switch (workspace) {
41
- case true:
42
- return (0, workspace_1.default)(argv, prompter);
43
- case false:
44
- default:
45
- return (0, module_1.default)(argv, prompter);
43
+ const firstArg = argv._?.[0] || undefined;
44
+ if (firstArg === 'workspace') {
45
+ const nextArgv = {
46
+ ...argv,
47
+ _: (argv._ ?? []).slice(1)
48
+ };
49
+ return (0, workspace_1.default)(nextArgv, prompter);
46
50
  }
51
+ return (0, module_1.default)(argv, prompter);
47
52
  }
@@ -6,7 +6,6 @@ const logger_1 = require("@launchql/logger");
6
6
  const types_1 = require("@launchql/types");
7
7
  const log = new logger_1.Logger('module-init');
8
8
  async function runModuleSetup(argv, prompter) {
9
- const { email, username } = (0, types_1.getGitConfigInfo)();
10
9
  const { cwd = process.cwd() } = argv;
11
10
  const project = new core_1.LaunchQLPackage(cwd);
12
11
  if (!project.workspacePath) {
@@ -20,7 +19,7 @@ async function runModuleSetup(argv, prompter) {
20
19
  const availExtensions = project.getAvailableModules();
21
20
  const moduleQuestions = [
22
21
  {
23
- name: 'MODULENAME',
22
+ name: 'moduleName',
24
23
  message: 'Enter the module name',
25
24
  required: true,
26
25
  type: 'text',
@@ -35,36 +34,31 @@ async function runModuleSetup(argv, prompter) {
35
34
  },
36
35
  ];
37
36
  const answers = await prompter.prompt(argv, moduleQuestions);
38
- const modName = (0, core_1.sluggify)(answers.MODULENAME);
37
+ const modName = (0, core_1.sluggify)(answers.moduleName);
38
+ // Avoid overlapping readline listeners with create-gen-app's prompts.
39
+ prompter.close();
39
40
  const extensions = answers.extensions
40
41
  .filter((opt) => opt.selected)
41
42
  .map((opt) => opt.name);
42
- // Determine template source
43
- let templateSource;
44
- if (argv.repo) {
45
- templateSource = {
46
- type: 'github',
47
- path: argv.repo,
48
- branch: argv.fromBranch
49
- };
50
- log.info(`Loading templates from GitHub repository: ${argv.repo}`);
51
- }
52
- else if (argv.templatePath) {
53
- templateSource = {
54
- type: 'local',
55
- path: argv.templatePath
56
- };
57
- log.info(`Loading templates from local path: ${argv.templatePath}`);
58
- }
59
- project.initModule({
43
+ const templateRepo = argv.repo ?? core_1.DEFAULT_TEMPLATE_REPO;
44
+ const templatePath = argv.templatePath;
45
+ const templateAnswers = {
60
46
  ...argv,
61
47
  ...answers,
48
+ moduleName: modName,
49
+ packageIdentifier: argv.packageIdentifier || modName
50
+ };
51
+ await project.initModule({
62
52
  name: modName,
63
- // @ts-ignore
64
- USERFULLNAME: username,
65
- USEREMAIL: email,
53
+ description: answers.description || modName,
54
+ author: answers.author || modName,
66
55
  extensions,
67
- templateSource
56
+ templateRepo,
57
+ templatePath,
58
+ branch: argv.fromBranch,
59
+ toolName: core_1.DEFAULT_TEMPLATE_TOOL_NAME,
60
+ answers: templateAnswers,
61
+ noTty: Boolean(argv.noTty || argv['no-tty'] || process.env.CI === 'true')
68
62
  });
69
63
  log.success(`Initialized module: ${modName}`);
70
64
  return { ...argv, ...answers };
@@ -6,9 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = runWorkspaceSetup;
7
7
  const core_1 = require("@launchql/core");
8
8
  const logger_1 = require("@launchql/logger");
9
- // @ts-ignore - TypeScript module resolution issue with @launchql/templatizer
10
- const templatizer_1 = require("@launchql/templatizer");
11
- const fs_1 = require("fs");
12
9
  const path_1 = __importDefault(require("path"));
13
10
  const log = new logger_1.Logger('workspace-init');
14
11
  async function runWorkspaceSetup(argv, prompter) {
@@ -17,36 +14,35 @@ async function runWorkspaceSetup(argv, prompter) {
17
14
  name: 'name',
18
15
  message: 'Enter workspace name',
19
16
  required: true,
20
- type: 'text',
17
+ type: 'text'
21
18
  }
22
19
  ];
23
20
  const answers = await prompter.prompt(argv, workspaceQuestions);
24
- const { cwd } = argv;
21
+ const { cwd = process.cwd() } = argv;
25
22
  const targetPath = path_1.default.join(cwd, (0, core_1.sluggify)(answers.name));
26
- (0, fs_1.mkdirSync)(targetPath, { recursive: true });
27
- log.success(`Created workspace directory: ${targetPath}`);
28
- // Determine template source
29
- let templates = templatizer_1.workspaceTemplate;
30
- if (argv.repo) {
31
- const source = {
32
- type: 'github',
33
- path: argv.repo,
34
- branch: argv.fromBranch
35
- };
36
- log.info(`Loading templates from GitHub repository: ${argv.repo}`);
37
- const compiledTemplates = (0, templatizer_1.loadTemplates)(source, 'workspace');
38
- templates = compiledTemplates.map((t) => t.render);
39
- }
40
- else if (argv.templatePath) {
41
- const source = {
42
- type: 'local',
43
- path: argv.templatePath
44
- };
45
- log.info(`Loading templates from local path: ${argv.templatePath}`);
46
- const compiledTemplates = (0, templatizer_1.loadTemplates)(source, 'workspace');
47
- templates = compiledTemplates.map((t) => t.render);
48
- }
49
- (0, templatizer_1.writeRenderedTemplates)(templates, targetPath, { ...argv, ...answers });
23
+ // Prevent double-echoed keystrokes by closing our prompter before template prompts.
24
+ prompter.close();
25
+ const templateRepo = argv.repo ?? core_1.DEFAULT_TEMPLATE_REPO;
26
+ const templatePath = argv.templatePath ?? 'workspace';
27
+ const scaffoldResult = await (0, core_1.scaffoldTemplate)({
28
+ type: 'workspace',
29
+ outputDir: targetPath,
30
+ templateRepo,
31
+ branch: argv.fromBranch,
32
+ templatePath,
33
+ answers: {
34
+ ...argv,
35
+ ...answers,
36
+ workspaceName: answers.name
37
+ },
38
+ toolName: core_1.DEFAULT_TEMPLATE_TOOL_NAME,
39
+ noTty: Boolean(argv.noTty || argv['no-tty'] || process.env.CI === 'true'),
40
+ cwd
41
+ });
42
+ const cacheMessage = scaffoldResult.cacheUsed
43
+ ? `Using cached templates from ${scaffoldResult.templateDir}`
44
+ : `Fetched templates into ${scaffoldResult.templateDir}`;
45
+ log.success(cacheMessage);
50
46
  log.success('Workspace templates rendered.');
51
47
  return { ...argv, ...answers, cwd: targetPath };
52
48
  }
@@ -0,0 +1,3 @@
1
+ import { CLIOptions, Inquirerer } from 'inquirerer';
2
+ declare const _default: (argv: Partial<Record<string, any>>, _prompter: Inquirerer, _options: CLIOptions) => Promise<Partial<Record<string, any>>>;
3
+ export default _default;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const logger_1 = require("@launchql/logger");
4
+ const child_process_1 = require("child_process");
5
+ const package_1 = require("../package");
6
+ const npm_version_1 = require("../utils/npm-version");
7
+ const cli_error_1 = require("../utils/cli-error");
8
+ const log = new logger_1.Logger('update');
9
+ const updateUsageText = `
10
+ Update Command:
11
+
12
+ pgpm update [OPTIONS]
13
+
14
+ Install the latest version of pgpm from npm.
15
+
16
+ Options:
17
+ --help, -h Show this help message
18
+ --package <name> Override the package name (default: package.json name)
19
+ --registry <url> Use a custom npm registry
20
+ --dry-run Print the npm command without executing it
21
+ `;
22
+ const runNpmInstall = (pkgName, registry) => {
23
+ return new Promise((resolve, reject) => {
24
+ const args = ['install', '-g', pkgName];
25
+ if (registry) {
26
+ args.push('--registry', registry);
27
+ }
28
+ const child = (0, child_process_1.spawn)('npm', args, { stdio: 'inherit' });
29
+ child.on('error', reject);
30
+ child.on('exit', (code) => {
31
+ if (code === 0) {
32
+ resolve();
33
+ }
34
+ else {
35
+ reject(new Error(`npm install exited with code ${code}`));
36
+ }
37
+ });
38
+ });
39
+ };
40
+ exports.default = async (argv, _prompter, _options) => {
41
+ if (argv.help || argv.h) {
42
+ console.log(updateUsageText);
43
+ process.exit(0);
44
+ }
45
+ const pkgJson = (0, package_1.readAndParsePackageJson)();
46
+ const pkgName = argv.package || pkgJson.name || 'pgpm';
47
+ const registry = argv.registry;
48
+ const dryRun = Boolean(argv['dry-run']);
49
+ const npmCommand = `npm install -g ${pkgName}${registry ? ` --registry ${registry}` : ''}`;
50
+ if (dryRun) {
51
+ log.info(`[dry-run] ${npmCommand}`);
52
+ return argv;
53
+ }
54
+ log.info(`Running: ${npmCommand}`);
55
+ try {
56
+ await runNpmInstall(pkgName, registry);
57
+ const latest = await (0, npm_version_1.fetchLatestVersion)(pkgName);
58
+ if (latest) {
59
+ log.success(`Successfully updated ${pkgName} to version ${latest}.`);
60
+ }
61
+ else {
62
+ log.success(`npm install completed for ${pkgName}.`);
63
+ }
64
+ }
65
+ catch (error) {
66
+ await (0, cli_error_1.cliExitWithError)(error instanceof Error ? error.message : String(error), { package: pkgName, registry });
67
+ }
68
+ return argv;
69
+ };
package/commands.js CHANGED
@@ -8,6 +8,7 @@ const pg_cache_1 = require("pg-cache");
8
8
  const add_1 = __importDefault(require("./commands/add"));
9
9
  const admin_users_1 = __importDefault(require("./commands/admin-users"));
10
10
  const analyze_1 = __importDefault(require("./commands/analyze"));
11
+ const cache_1 = __importDefault(require("./commands/cache"));
11
12
  const clear_1 = __importDefault(require("./commands/clear"));
12
13
  const deploy_1 = __importDefault(require("./commands/deploy"));
13
14
  const docker_1 = __importDefault(require("./commands/docker"));
@@ -20,6 +21,7 @@ const kill_1 = __importDefault(require("./commands/kill"));
20
21
  const migrate_1 = __importDefault(require("./commands/migrate"));
21
22
  const package_1 = __importDefault(require("./commands/package"));
22
23
  const plan_1 = __importDefault(require("./commands/plan"));
24
+ const update_1 = __importDefault(require("./commands/update"));
23
25
  const remove_1 = __importDefault(require("./commands/remove"));
24
26
  const rename_1 = __importDefault(require("./commands/rename"));
25
27
  const revert_1 = __importDefault(require("./commands/revert"));
@@ -28,6 +30,7 @@ const verify_1 = __importDefault(require("./commands/verify"));
28
30
  const package_2 = require("./package");
29
31
  const utils_1 = require("./utils");
30
32
  const cli_error_1 = require("./utils/cli-error");
33
+ const update_check_1 = require("./utils/update-check");
31
34
  const withPgTeardown = (fn, skipTeardown = false) => async (...args) => {
32
35
  try {
33
36
  await fn(...args);
@@ -60,7 +63,9 @@ const createPgpmCommandMap = (skipPgTeardown = false) => {
60
63
  install: pgt(install_1.default),
61
64
  migrate: pgt(migrate_1.default),
62
65
  analyze: pgt(analyze_1.default),
63
- rename: pgt(rename_1.default)
66
+ rename: pgt(rename_1.default),
67
+ cache: cache_1.default,
68
+ update: update_1.default
64
69
  };
65
70
  };
66
71
  exports.createPgpmCommandMap = createPgpmCommandMap;
@@ -91,6 +96,15 @@ const commands = async (argv, prompter, options) => {
91
96
  ]);
92
97
  command = answer.command;
93
98
  }
99
+ try {
100
+ await (0, update_check_1.checkForUpdates)({
101
+ command,
102
+ pkgVersion: (0, package_2.readAndParsePackageJson)().version
103
+ });
104
+ }
105
+ catch {
106
+ // ignore update check failures
107
+ }
94
108
  newArgv = await prompter.prompt(newArgv, [
95
109
  {
96
110
  type: 'text',
@@ -0,0 +1,30 @@
1
+ import { Logger } from '@launchql/logger';
2
+ import { CacheManager } from 'create-gen-app';
3
+ import { cliExitWithError } from '../utils/cli-error';
4
+ const log = new Logger('cache');
5
+ const cacheUsageText = `
6
+ Cache Command:
7
+
8
+ pgpm cache clean [OPTIONS]
9
+
10
+ Options:
11
+ --help, -h Show this help message
12
+ --tool <name> Cache namespace to clear (default: pgpm)
13
+ `;
14
+ export default async (argv, _prompter, _options) => {
15
+ if (argv.help || argv.h) {
16
+ console.log(cacheUsageText);
17
+ process.exit(0);
18
+ }
19
+ const action = argv._?.[0] || 'clean';
20
+ if (action !== 'clean') {
21
+ console.log(cacheUsageText);
22
+ await cliExitWithError(`Unknown cache action: ${action}`);
23
+ }
24
+ const toolName = argv.tool || 'pgpm';
25
+ const cacheManager = new CacheManager({ toolName });
26
+ cacheManager.clearAll();
27
+ log.success(`Cleared template cache for "${toolName}".`);
28
+ log.debug(`Cache location: ${cacheManager.getReposDir()}`);
29
+ return argv;
30
+ };