@forgecart/cli 1.0.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.
Files changed (93) hide show
  1. package/README.md +179 -0
  2. package/bin/forgecart.js +3 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +30 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/delete.d.ts +3 -0
  8. package/dist/commands/delete.d.ts.map +1 -0
  9. package/dist/commands/delete.js +55 -0
  10. package/dist/commands/delete.js.map +1 -0
  11. package/dist/commands/deploy.d.ts +3 -0
  12. package/dist/commands/deploy.d.ts.map +1 -0
  13. package/dist/commands/deploy.js +128 -0
  14. package/dist/commands/deploy.js.map +1 -0
  15. package/dist/commands/env.d.ts +3 -0
  16. package/dist/commands/env.d.ts.map +1 -0
  17. package/dist/commands/env.js +100 -0
  18. package/dist/commands/env.js.map +1 -0
  19. package/dist/commands/init.d.ts +4 -0
  20. package/dist/commands/init.d.ts.map +1 -0
  21. package/dist/commands/init.js +233 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/commands/list.d.ts +3 -0
  24. package/dist/commands/list.d.ts.map +1 -0
  25. package/dist/commands/list.js +61 -0
  26. package/dist/commands/list.js.map +1 -0
  27. package/dist/commands/logs.d.ts +3 -0
  28. package/dist/commands/logs.d.ts.map +1 -0
  29. package/dist/commands/logs.js +105 -0
  30. package/dist/commands/logs.js.map +1 -0
  31. package/dist/commands/scale.d.ts +3 -0
  32. package/dist/commands/scale.d.ts.map +1 -0
  33. package/dist/commands/scale.js +45 -0
  34. package/dist/commands/scale.js.map +1 -0
  35. package/dist/commands/status.d.ts +3 -0
  36. package/dist/commands/status.d.ts.map +1 -0
  37. package/dist/commands/status.js +85 -0
  38. package/dist/commands/status.js.map +1 -0
  39. package/dist/commands/whoami.d.ts +3 -0
  40. package/dist/commands/whoami.d.ts.map +1 -0
  41. package/dist/commands/whoami.js +46 -0
  42. package/dist/commands/whoami.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +5 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/api-client.d.ts +21 -0
  48. package/dist/lib/api-client.d.ts.map +1 -0
  49. package/dist/lib/api-client.js +220 -0
  50. package/dist/lib/api-client.js.map +1 -0
  51. package/dist/lib/archive.d.ts +8 -0
  52. package/dist/lib/archive.d.ts.map +1 -0
  53. package/dist/lib/archive.js +96 -0
  54. package/dist/lib/archive.js.map +1 -0
  55. package/dist/lib/config.d.ts +12 -0
  56. package/dist/lib/config.d.ts.map +1 -0
  57. package/dist/lib/config.js +79 -0
  58. package/dist/lib/config.js.map +1 -0
  59. package/dist/lib/logger.d.ts +15 -0
  60. package/dist/lib/logger.d.ts.map +1 -0
  61. package/dist/lib/logger.js +54 -0
  62. package/dist/lib/logger.js.map +1 -0
  63. package/dist/lib/nx-generator.d.ts +8 -0
  64. package/dist/lib/nx-generator.d.ts.map +1 -0
  65. package/dist/lib/nx-generator.js +146 -0
  66. package/dist/lib/nx-generator.js.map +1 -0
  67. package/dist/templates/application-additions/.forgecartignore +37 -0
  68. package/dist/templates/application-additions/Procfile +1 -0
  69. package/dist/templates/application-additions/src/services/price-fetcher.service.ts +72 -0
  70. package/dist/templates/storefront-additions/.forgecartignore +40 -0
  71. package/dist/templates/storefront-additions/Procfile +1 -0
  72. package/dist/templates/storefront-additions/src/app/products/page.tsx +78 -0
  73. package/dist/templates/storefront-additions/src/lib/forgecart.ts +11 -0
  74. package/dist/types/index.d.ts +70 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/index.js +14 -0
  77. package/dist/types/index.js.map +1 -0
  78. package/dist/utils/spinner.d.ts +4 -0
  79. package/dist/utils/spinner.d.ts.map +1 -0
  80. package/dist/utils/spinner.js +20 -0
  81. package/dist/utils/spinner.js.map +1 -0
  82. package/dist/utils/validation.d.ts +12 -0
  83. package/dist/utils/validation.d.ts.map +1 -0
  84. package/dist/utils/validation.js +66 -0
  85. package/dist/utils/validation.js.map +1 -0
  86. package/package.json +52 -0
  87. package/templates/application-additions/.forgecartignore +37 -0
  88. package/templates/application-additions/Procfile +1 -0
  89. package/templates/application-additions/src/services/price-fetcher.service.ts +72 -0
  90. package/templates/storefront-additions/.forgecartignore +40 -0
  91. package/templates/storefront-additions/Procfile +1 -0
  92. package/templates/storefront-additions/src/app/products/page.tsx +78 -0
  93. package/templates/storefront-additions/src/lib/forgecart.ts +11 -0
@@ -0,0 +1,233 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ import inquirer from 'inquirer';
4
+ import { Command } from 'commander';
5
+ import logger from '../lib/logger.js';
6
+ import { writeConfig, getDefaultConfig, configExists, readConfig, updateConfig, } from '../lib/config.js';
7
+ import { ForgecartApiClient } from '../lib/api-client.js';
8
+ import { createNxWorkspace, generateNextApp, generateNestApp, installDependency, copyTemplateFiles, getCliTemplatesDir, } from '../lib/nx-generator.js';
9
+ import { isValidProjectName } from '../utils/validation.js';
10
+ import { withSpinner } from '../utils/spinner.js';
11
+ export function createInitCommand() {
12
+ const cmd = new Command('init')
13
+ .description('Create a new ForgéCart project')
14
+ .argument('[name]', 'Project name')
15
+ .option('-t, --token <token>', 'ForgéCart channel token')
16
+ .option('-a, --application', 'Include NestJS backend application')
17
+ .option('--api-url <url>', 'ForgéCart API URL', 'https://api.forgecart.com')
18
+ .action(async (name, options) => {
19
+ await initProject(name, options);
20
+ });
21
+ return cmd;
22
+ }
23
+ export function createInitApplicationCommand() {
24
+ const cmd = new Command('init:application')
25
+ .description('Add a NestJS backend application to an existing project')
26
+ .action(async () => {
27
+ await addApplication();
28
+ });
29
+ return cmd;
30
+ }
31
+ async function initProject(name, options) {
32
+ logger.title('ForgéCart Project Setup');
33
+ // Prompt for project name if not provided
34
+ let projectName = name;
35
+ if (!projectName) {
36
+ const answers = await inquirer.prompt([
37
+ {
38
+ type: 'input',
39
+ name: 'projectName',
40
+ message: 'Project name:',
41
+ validate: (input) => {
42
+ if (!input)
43
+ return 'Project name is required';
44
+ if (!isValidProjectName(input)) {
45
+ return 'Project name must start with a letter and contain only lowercase letters, numbers, and hyphens';
46
+ }
47
+ return true;
48
+ },
49
+ },
50
+ ]);
51
+ projectName = answers.projectName;
52
+ }
53
+ // Validate project name
54
+ if (!projectName || !isValidProjectName(projectName)) {
55
+ logger.error('Invalid project name. Must start with a letter and contain only lowercase letters, numbers, and hyphens.');
56
+ process.exit(1);
57
+ }
58
+ // Check if directory already exists
59
+ const targetDir = path.join(process.cwd(), projectName);
60
+ if (fs.existsSync(targetDir)) {
61
+ logger.error(`Directory ${projectName} already exists`);
62
+ process.exit(1);
63
+ }
64
+ // Prompt for channel token if not provided
65
+ let channelToken = options.channelToken;
66
+ if (!channelToken) {
67
+ const answers = await inquirer.prompt([
68
+ {
69
+ type: 'input',
70
+ name: 'channelToken',
71
+ message: 'ForgéCart channel token:',
72
+ validate: (input) => {
73
+ if (!input)
74
+ return 'Channel token is required';
75
+ return true;
76
+ },
77
+ },
78
+ ]);
79
+ channelToken = answers.channelToken;
80
+ }
81
+ // Validate channel token
82
+ if (!channelToken) {
83
+ logger.error('Channel token is required');
84
+ process.exit(1);
85
+ }
86
+ const apiUrl = options.apiUrl || 'https://api.forgecart.com';
87
+ const apiClient = new ForgecartApiClient(apiUrl, channelToken);
88
+ await withSpinner('Validating channel token...', 'Channel token validated', 'Invalid channel token', async () => {
89
+ const isValid = await apiClient.validateChannelToken();
90
+ if (!isValid) {
91
+ throw new Error('Invalid channel token');
92
+ }
93
+ });
94
+ // Prompt for application inclusion if not specified
95
+ let withApplication = options.withApplication;
96
+ if (withApplication === undefined) {
97
+ const answers = await inquirer.prompt([
98
+ {
99
+ type: 'confirm',
100
+ name: 'withApplication',
101
+ message: 'Include NestJS backend application?',
102
+ default: false,
103
+ },
104
+ ]);
105
+ withApplication = answers.withApplication;
106
+ }
107
+ // Create NX workspace
108
+ await withSpinner('Creating NX workspace...', 'NX workspace created', 'Failed to create NX workspace', async () => {
109
+ const success = await createNxWorkspace(projectName, process.cwd());
110
+ if (!success) {
111
+ throw new Error('Failed to create NX workspace');
112
+ }
113
+ });
114
+ // Generate Next.js storefront
115
+ await withSpinner('Generating Next.js storefront...', 'Storefront generated', 'Failed to generate storefront', async () => {
116
+ const success = await generateNextApp('storefront', targetDir);
117
+ if (!success) {
118
+ throw new Error('Failed to generate storefront');
119
+ }
120
+ });
121
+ // Install @forgecart/sdk
122
+ await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
123
+ const success = await installDependency('@forgecart/sdk', targetDir);
124
+ if (!success) {
125
+ throw new Error('Failed to install SDK');
126
+ }
127
+ });
128
+ // Copy storefront template additions
129
+ logger.info('Applying storefront customizations...');
130
+ const templatesDir = getCliTemplatesDir();
131
+ const storefrontAdditionsDir = path.join(templatesDir, 'storefront-additions');
132
+ const storefrontDir = path.join(targetDir, 'apps', 'storefront');
133
+ copyTemplateFiles(storefrontAdditionsDir, storefrontDir);
134
+ logger.success('Storefront customizations applied');
135
+ // Generate NestJS application if requested
136
+ if (withApplication) {
137
+ await withSpinner('Generating NestJS application...', 'Application generated', 'Failed to generate application', async () => {
138
+ const success = await generateNestApp('application', targetDir);
139
+ if (!success) {
140
+ throw new Error('Failed to generate application');
141
+ }
142
+ });
143
+ // Copy application template additions
144
+ logger.info('Applying application customizations...');
145
+ const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
146
+ const applicationDir = path.join(targetDir, 'apps', 'application');
147
+ copyTemplateFiles(applicationAdditionsDir, applicationDir);
148
+ logger.success('Application customizations applied');
149
+ }
150
+ // Create ForgéCart config
151
+ const config = getDefaultConfig();
152
+ config.channelToken = channelToken;
153
+ config.apiUrl = apiUrl;
154
+ config.hasApplication = withApplication || false;
155
+ config.storefrontPath = 'apps/storefront';
156
+ if (withApplication) {
157
+ config.applicationPath = 'apps/application';
158
+ }
159
+ writeConfig(config, targetDir);
160
+ logger.success('ForgéCart configuration created');
161
+ // Success message
162
+ logger.newline();
163
+ logger.box(`Project "${projectName}" created successfully!
164
+
165
+ Next steps:
166
+ cd ${projectName}
167
+ forgecart deploy
168
+
169
+ Your storefront will be available at:
170
+ apps/storefront/` +
171
+ (withApplication
172
+ ? `
173
+
174
+ Your application will be available at:
175
+ apps/application/`
176
+ : ''));
177
+ }
178
+ async function addApplication() {
179
+ logger.title('Add NestJS Application');
180
+ // Check if we're in a ForgéCart project
181
+ if (!configExists()) {
182
+ logger.error('Not in a ForgéCart project. Run "forgecart init" first.');
183
+ process.exit(1);
184
+ }
185
+ const config = readConfig();
186
+ if (!config) {
187
+ logger.error('Invalid ForgéCart configuration');
188
+ process.exit(1);
189
+ }
190
+ // Check if application already exists
191
+ if (config.hasApplication) {
192
+ logger.error('Application already exists in this project');
193
+ process.exit(1);
194
+ }
195
+ const projectRoot = process.cwd();
196
+ // Generate NestJS application
197
+ await withSpinner('Generating NestJS application...', 'Application generated', 'Failed to generate application', async () => {
198
+ const success = await generateNestApp('application', projectRoot);
199
+ if (!success) {
200
+ throw new Error('Failed to generate application');
201
+ }
202
+ });
203
+ // Install @forgecart/sdk in application
204
+ await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
205
+ const success = await installDependency('@forgecart/sdk', projectRoot);
206
+ if (!success) {
207
+ throw new Error('Failed to install SDK');
208
+ }
209
+ });
210
+ // Copy application template additions
211
+ logger.info('Applying application customizations...');
212
+ const templatesDir = getCliTemplatesDir();
213
+ const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
214
+ const applicationDir = path.join(projectRoot, 'apps', 'application');
215
+ copyTemplateFiles(applicationAdditionsDir, applicationDir);
216
+ logger.success('Application customizations applied');
217
+ // Update config
218
+ updateConfig({
219
+ hasApplication: true,
220
+ applicationPath: 'apps/application',
221
+ });
222
+ logger.success('Configuration updated');
223
+ logger.newline();
224
+ logger.box(`NestJS application added successfully!
225
+
226
+ Your application is available at:
227
+ apps/application/
228
+
229
+ To deploy:
230
+ cd apps/application
231
+ forgecart deploy`);
232
+ }
233
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createListCommand(): Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,wBAAgB,iBAAiB,IAAI,OAAO,CAS3C"}
@@ -0,0 +1,61 @@
1
+ import { Command } from 'commander';
2
+ import Table from 'cli-table3';
3
+ import chalk from 'chalk';
4
+ import logger from '../lib/logger.js';
5
+ import { requireConfig } from '../lib/config.js';
6
+ import { ForgecartApiClient } from '../lib/api-client.js';
7
+ import { DeploymentStatus } from '../types/index.js';
8
+ export function createListCommand() {
9
+ const cmd = new Command('list')
10
+ .alias('ls')
11
+ .description('List all deployments for this channel')
12
+ .action(async () => {
13
+ await listDeployments();
14
+ });
15
+ return cmd;
16
+ }
17
+ function getStatusColor(status) {
18
+ switch (status) {
19
+ case DeploymentStatus.RUNNING:
20
+ return chalk.green(status);
21
+ case DeploymentStatus.STAGING:
22
+ return chalk.yellow(status);
23
+ case DeploymentStatus.PENDING:
24
+ return chalk.blue(status);
25
+ case DeploymentStatus.ERROR:
26
+ return chalk.red(status);
27
+ case DeploymentStatus.STOPPED:
28
+ return chalk.gray(status);
29
+ default:
30
+ return status;
31
+ }
32
+ }
33
+ async function listDeployments() {
34
+ const config = requireConfig();
35
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
36
+ const deployments = await apiClient.getDeployments();
37
+ if (deployments.length === 0) {
38
+ logger.info('No deployments found');
39
+ logger.log('Run "forgecart deploy" to deploy your application');
40
+ return;
41
+ }
42
+ const table = new Table({
43
+ head: ['Type', 'Status', 'URL', 'Instances', 'Last Deployed'],
44
+ style: {
45
+ head: ['cyan'],
46
+ },
47
+ });
48
+ for (const deployment of deployments) {
49
+ table.push([
50
+ deployment.type,
51
+ getStatusColor(deployment.status),
52
+ deployment.url || '-',
53
+ deployment.instances.toString(),
54
+ deployment.lastDeployedAt
55
+ ? new Date(deployment.lastDeployedAt).toLocaleString()
56
+ : '-',
57
+ ]);
58
+ }
59
+ console.log(table.toString());
60
+ }
61
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,MAAM,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC5B,KAAK,CAAC,IAAI,CAAC;SACX,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,eAAe,EAAE,CAAA;IACzB,CAAC,CAAC,CAAA;IAEJ,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,cAAc,CAAC,MAAwB;IAC9C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC5B,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC7B,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3B,KAAK,gBAAgB,CAAC,KAAK;YACzB,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC1B,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3B;YACE,OAAO,MAAM,CAAA;IACjB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAE5E,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE,CAAA;IAEpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;QAC/D,OAAM;IACR,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,CAAC;QAC7D,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,MAAM,CAAC;SACf;KACF,CAAC,CAAA;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC;YACT,UAAU,CAAC,IAAI;YACf,cAAc,CAAC,UAAU,CAAC,MAA0B,CAAC;YACrD,UAAU,CAAC,GAAG,IAAI,GAAG;YACrB,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC/B,UAAU,CAAC,cAAc;gBACvB,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,cAAc,EAAE;gBACtD,CAAC,CAAC,GAAG;SACR,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createLogsCommand(): Command;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,wBAAgB,iBAAiB,IAAI,OAAO,CAiB3C"}
@@ -0,0 +1,105 @@
1
+ import { Command } from 'commander';
2
+ import WebSocket from 'ws';
3
+ import chalk from 'chalk';
4
+ import logger from '../lib/logger.js';
5
+ import { requireConfig } from '../lib/config.js';
6
+ import { ForgecartApiClient } from '../lib/api-client.js';
7
+ import { DeploymentType } from '../types/index.js';
8
+ export function createLogsCommand() {
9
+ const cmd = new Command('logs')
10
+ .description('View deployment logs')
11
+ .argument('[type]', 'Deployment type (storefront or application)', 'storefront')
12
+ .option('-f, --follow', 'Follow log output')
13
+ .option('-n, --lines <number>', 'Number of lines to show', '100')
14
+ .action(async (type, options) => {
15
+ await viewLogs(type, options);
16
+ });
17
+ return cmd;
18
+ }
19
+ async function viewLogs(type, options) {
20
+ // Validate type
21
+ if (type !== DeploymentType.STOREFRONT &&
22
+ type !== DeploymentType.APPLICATION) {
23
+ logger.error('Invalid deployment type. Use "storefront" or "application".');
24
+ process.exit(1);
25
+ }
26
+ const config = requireConfig();
27
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
28
+ // Check if deployment exists
29
+ const deployment = await apiClient.getDeployment(type);
30
+ if (!deployment) {
31
+ logger.error(`No ${type} deployment found`);
32
+ process.exit(1);
33
+ }
34
+ // Get WebSocket URL for logs
35
+ const wsUrl = await apiClient.getLogsWebSocketUrl(type);
36
+ if (!wsUrl) {
37
+ logger.error('Unable to get logs URL');
38
+ process.exit(1);
39
+ }
40
+ logger.info(`Connecting to ${type} logs...`);
41
+ // Connect to WebSocket
42
+ const ws = new WebSocket(wsUrl, {
43
+ headers: {
44
+ Authorization: `Basic ${Buffer.from(`${config.channelToken}:`).toString('base64')}`,
45
+ },
46
+ });
47
+ ws.on('open', () => {
48
+ logger.success(`Connected to ${type} logs`);
49
+ logger.info('Press Ctrl+C to stop');
50
+ logger.newline();
51
+ });
52
+ ws.on('message', (data) => {
53
+ const message = data.toString();
54
+ // Parse and format log message
55
+ try {
56
+ const logEntry = JSON.parse(message);
57
+ const timestamp = new Date(logEntry.timestamp || Date.now()).toISOString();
58
+ const level = logEntry.level || 'info';
59
+ const text = logEntry.message || message;
60
+ let coloredLevel;
61
+ switch (level.toLowerCase()) {
62
+ case 'error':
63
+ coloredLevel = chalk.red(level.toUpperCase());
64
+ break;
65
+ case 'warn':
66
+ case 'warning':
67
+ coloredLevel = chalk.yellow(level.toUpperCase());
68
+ break;
69
+ case 'debug':
70
+ coloredLevel = chalk.gray(level.toUpperCase());
71
+ break;
72
+ default:
73
+ coloredLevel = chalk.blue(level.toUpperCase());
74
+ }
75
+ console.log(`${chalk.gray(timestamp)} ${coloredLevel} ${text}`);
76
+ }
77
+ catch {
78
+ // Plain text log
79
+ console.log(message);
80
+ }
81
+ });
82
+ ws.on('error', (error) => {
83
+ logger.error(`WebSocket error: ${error.message}`);
84
+ });
85
+ ws.on('close', () => {
86
+ logger.info('Disconnected from logs');
87
+ if (!options.follow) {
88
+ process.exit(0);
89
+ }
90
+ });
91
+ // Handle Ctrl+C
92
+ process.on('SIGINT', () => {
93
+ logger.newline();
94
+ logger.info('Disconnecting...');
95
+ ws.close();
96
+ process.exit(0);
97
+ });
98
+ // If not following, close after a timeout
99
+ if (!options.follow) {
100
+ setTimeout(() => {
101
+ ws.close();
102
+ }, 5000);
103
+ }
104
+ }
105
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,SAAS,MAAM,IAAI,CAAA;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,MAAM,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC5B,WAAW,CAAC,sBAAsB,CAAC;SACnC,QAAQ,CACP,QAAQ,EACR,6CAA6C,EAC7C,YAAY,CACb;SACA,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC;SAC3C,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,EAAE,KAAK,CAAC;SAChE,MAAM,CACL,KAAK,EAAE,IAAY,EAAE,OAA6C,EAAE,EAAE;QACpE,MAAM,QAAQ,CAAC,IAAsB,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC,CACF,CAAA;IAEH,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,IAAoB,EACpB,OAA6C;IAE7C,gBAAgB;IAChB,IACE,IAAI,KAAK,cAAc,CAAC,UAAU;QAClC,IAAI,KAAK,cAAc,CAAC,WAAW,EACnC,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAA;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAE5E,6BAA6B;IAC7B,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IACtD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,mBAAmB,CAAC,CAAA;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,6BAA6B;IAC7B,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACvD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,iBAAiB,IAAI,UAAU,CAAC,CAAA;IAE5C,uBAAuB;IACvB,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE;QAC9B,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;SACpF;KACF,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACjB,MAAM,CAAC,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,CAAA;QAC3C,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QACnC,MAAM,CAAC,OAAO,EAAE,CAAA;IAClB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAoB,EAAE,EAAE;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;QAE/B,+BAA+B;QAC/B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACpC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;YAC1E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAA;YACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAA;YAExC,IAAI,YAAoB,CAAA;YACxB,QAAQ,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC5B,KAAK,OAAO;oBACV,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;oBAC7C,MAAK;gBACP,KAAK,MAAM,CAAC;gBACZ,KAAK,SAAS;oBACZ,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;oBAChD,MAAK;gBACP,KAAK,OAAO;oBACV,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;oBAC9C,MAAK;gBACP;oBACE,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;YAClD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC,CAAA;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;YACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACtB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QAC9B,MAAM,CAAC,KAAK,CAAC,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;QACrC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,gBAAgB;IAChB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,OAAO,EAAE,CAAA;QAChB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC/B,EAAE,CAAC,KAAK,EAAE,CAAA;QACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,0CAA0C;IAC1C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,UAAU,CAAC,GAAG,EAAE;YACd,EAAE,CAAC,KAAK,EAAE,CAAA;QACZ,CAAC,EAAE,IAAI,CAAC,CAAA;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createScaleCommand(): Command;
3
+ //# sourceMappingURL=scale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../src/commands/scale.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAOnC,wBAAgB,kBAAkB,IAAI,OAAO,CAU5C"}
@@ -0,0 +1,45 @@
1
+ import { Command } from 'commander';
2
+ import logger from '../lib/logger.js';
3
+ import { requireConfig } from '../lib/config.js';
4
+ import { ForgecartApiClient } from '../lib/api-client.js';
5
+ import { DeploymentType } from '../types/index.js';
6
+ import { withSpinner } from '../utils/spinner.js';
7
+ export function createScaleCommand() {
8
+ const cmd = new Command('scale')
9
+ .description('Scale a deployment')
10
+ .argument('<type>', 'Deployment type (storefront or application)')
11
+ .argument('<instances>', 'Number of instances')
12
+ .action(async (type, instances) => {
13
+ await scaleDeployment(type, parseInt(instances, 10));
14
+ });
15
+ return cmd;
16
+ }
17
+ async function scaleDeployment(type, instances) {
18
+ // Validate type
19
+ if (type !== DeploymentType.STOREFRONT && type !== DeploymentType.APPLICATION) {
20
+ logger.error('Invalid deployment type. Use "storefront" or "application".');
21
+ process.exit(1);
22
+ }
23
+ // Validate instances
24
+ if (isNaN(instances) || instances < 0 || instances > 10) {
25
+ logger.error('Invalid number of instances. Must be between 0 and 10.');
26
+ process.exit(1);
27
+ }
28
+ const config = requireConfig();
29
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
30
+ // Check if deployment exists
31
+ const deployment = await apiClient.getDeployment(type);
32
+ if (!deployment) {
33
+ logger.error(`No ${type} deployment found`);
34
+ process.exit(1);
35
+ }
36
+ // Scale deployment
37
+ const scaled = await withSpinner(`Scaling ${type} to ${instances} instance(s)...`, `${type} scaled to ${instances} instance(s)`, `Failed to scale ${type}`, async () => {
38
+ return apiClient.scaleDeployment(type, instances);
39
+ });
40
+ logger.newline();
41
+ logger.keyValue('Type', scaled.type);
42
+ logger.keyValue('Instances', scaled.instances.toString());
43
+ logger.keyValue('Status', scaled.status);
44
+ }
45
+ //# sourceMappingURL=scale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale.js","sourceRoot":"","sources":["../../src/commands/scale.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,MAAM,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC7B,WAAW,CAAC,oBAAoB,CAAC;SACjC,QAAQ,CAAC,QAAQ,EAAE,6CAA6C,CAAC;SACjE,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;SAC9C,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,SAAiB,EAAE,EAAE;QAChD,MAAM,eAAe,CAAC,IAAsB,EAAE,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IAEJ,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAoB,EAAE,SAAiB;IACpE,gBAAgB;IAChB,IAAI,IAAI,KAAK,cAAc,CAAC,UAAU,IAAI,IAAI,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC;QAC9E,MAAM,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAA;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,qBAAqB;IACrB,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAA;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAE5E,6BAA6B;IAC7B,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IACtD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,mBAAmB,CAAC,CAAA;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,mBAAmB;IACnB,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,WAAW,IAAI,OAAO,SAAS,iBAAiB,EAChD,GAAG,IAAI,cAAc,SAAS,cAAc,EAC5C,mBAAmB,IAAI,EAAE,EACzB,KAAK,IAAI,EAAE;QACT,OAAO,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACnD,CAAC,CACF,CAAA;IAED,MAAM,CAAC,OAAO,EAAE,CAAA;IAChB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzD,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createStatusCommand(): Command;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,wBAAgB,mBAAmB,IAAI,OAAO,CAS7C"}
@@ -0,0 +1,85 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import logger from '../lib/logger.js';
4
+ import { requireConfig } from '../lib/config.js';
5
+ import { ForgecartApiClient } from '../lib/api-client.js';
6
+ import { DeploymentStatus } from '../types/index.js';
7
+ import { withSpinner } from '../utils/spinner.js';
8
+ export function createStatusCommand() {
9
+ const cmd = new Command('status')
10
+ .description('Show detailed deployment status')
11
+ .argument('[type]', 'Deployment type (storefront or application)')
12
+ .action(async (type) => {
13
+ await showStatus(type);
14
+ });
15
+ return cmd;
16
+ }
17
+ function getStatusColor(status) {
18
+ switch (status) {
19
+ case DeploymentStatus.RUNNING:
20
+ return chalk.green(status);
21
+ case DeploymentStatus.STAGING:
22
+ return chalk.yellow(status);
23
+ case DeploymentStatus.PENDING:
24
+ return chalk.blue(status);
25
+ case DeploymentStatus.ERROR:
26
+ return chalk.red(status);
27
+ case DeploymentStatus.STOPPED:
28
+ return chalk.gray(status);
29
+ default:
30
+ return status;
31
+ }
32
+ }
33
+ async function showStatus(type) {
34
+ const config = requireConfig();
35
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
36
+ if (type) {
37
+ // Show status for specific deployment
38
+ const deployment = await withSpinner('Fetching deployment status...', 'Status retrieved', 'Failed to fetch status', async () => {
39
+ return apiClient.refreshDeploymentStatus(type);
40
+ });
41
+ if (!deployment) {
42
+ logger.error(`No ${type} deployment found`);
43
+ return;
44
+ }
45
+ logger.newline();
46
+ logger.title(`${type} Deployment`);
47
+ logger.keyValue('ID', deployment.id);
48
+ logger.keyValue('Status', getStatusColor(deployment.status));
49
+ logger.keyValue('URL', deployment.url || 'Not available');
50
+ logger.keyValue('Instances', deployment.instances.toString());
51
+ logger.keyValue('Last Deployed', deployment.lastDeployedAt
52
+ ? new Date(deployment.lastDeployedAt).toLocaleString()
53
+ : 'Never');
54
+ if (deployment.errorMessage) {
55
+ logger.newline();
56
+ logger.error(`Error: ${deployment.errorMessage}`);
57
+ }
58
+ }
59
+ else {
60
+ // Show status for all deployments
61
+ const deployments = await withSpinner('Fetching deployment status...', 'Status retrieved', 'Failed to fetch status', async () => {
62
+ return apiClient.getDeployments();
63
+ });
64
+ if (deployments.length === 0) {
65
+ logger.info('No deployments found');
66
+ return;
67
+ }
68
+ for (const deployment of deployments) {
69
+ logger.newline();
70
+ logger.title(`${deployment.type} Deployment`);
71
+ logger.keyValue('ID', deployment.id);
72
+ logger.keyValue('Status', getStatusColor(deployment.status));
73
+ logger.keyValue('URL', deployment.url || 'Not available');
74
+ logger.keyValue('Instances', deployment.instances.toString());
75
+ logger.keyValue('Last Deployed', deployment.lastDeployedAt
76
+ ? new Date(deployment.lastDeployedAt).toLocaleString()
77
+ : 'Never');
78
+ if (deployment.errorMessage) {
79
+ logger.newline();
80
+ logger.error(`Error: ${deployment.errorMessage}`);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createWhoamiCommand(): Command;
3
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C"}