@forgecart/cli 1.0.0 → 1.1.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 (202) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -7
  3. package/bin/forgecart.js +1 -1
  4. package/dist/package.json +50 -0
  5. package/dist/src/cli.d.ts.map +1 -0
  6. package/dist/{cli.js → src/cli.js} +8 -6
  7. package/dist/src/cli.js.map +1 -0
  8. package/dist/src/commands/delete.d.ts.map +1 -0
  9. package/dist/{commands → src/commands}/delete.js +8 -3
  10. package/dist/src/commands/delete.js.map +1 -0
  11. package/dist/src/commands/deploy.d.ts.map +1 -0
  12. package/dist/src/commands/deploy.js +243 -0
  13. package/dist/src/commands/deploy.js.map +1 -0
  14. package/dist/src/commands/env.d.ts.map +1 -0
  15. package/dist/{commands → src/commands}/env.js +70 -12
  16. package/dist/src/commands/env.js.map +1 -0
  17. package/dist/src/commands/init.d.ts.map +1 -0
  18. package/dist/{commands → src/commands}/init.js +103 -17
  19. package/dist/src/commands/init.js.map +1 -0
  20. package/dist/src/commands/list.d.ts.map +1 -0
  21. package/dist/{commands → src/commands}/list.js +6 -2
  22. package/dist/src/commands/list.js.map +1 -0
  23. package/dist/src/commands/login.d.ts +3 -0
  24. package/dist/src/commands/login.d.ts.map +1 -0
  25. package/dist/src/commands/login.js +120 -0
  26. package/dist/src/commands/login.js.map +1 -0
  27. package/dist/src/commands/logs.d.ts.map +1 -0
  28. package/dist/src/commands/logs.js +88 -0
  29. package/dist/src/commands/logs.js.map +1 -0
  30. package/dist/src/commands/scale.d.ts.map +1 -0
  31. package/dist/{commands → src/commands}/scale.js +7 -3
  32. package/dist/src/commands/scale.js.map +1 -0
  33. package/dist/src/commands/status.d.ts.map +1 -0
  34. package/dist/{commands → src/commands}/status.js +7 -2
  35. package/dist/src/commands/status.js.map +1 -0
  36. package/dist/src/commands/whoami.d.ts.map +1 -0
  37. package/dist/{commands → src/commands}/whoami.js +20 -7
  38. package/dist/src/commands/whoami.js.map +1 -0
  39. package/dist/{index.d.ts.map → src/index.d.ts.map} +1 -1
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/lib/api-client.d.ts +34 -0
  42. package/dist/src/lib/api-client.d.ts.map +1 -0
  43. package/dist/src/lib/api-client.js +141 -0
  44. package/dist/src/lib/api-client.js.map +1 -0
  45. package/dist/{lib → src/lib}/archive.d.ts +2 -1
  46. package/dist/src/lib/archive.d.ts.map +1 -0
  47. package/dist/{lib → src/lib}/archive.js +27 -5
  48. package/dist/src/lib/archive.js.map +1 -0
  49. package/dist/src/lib/config-updater.d.ts +10 -0
  50. package/dist/src/lib/config-updater.d.ts.map +1 -0
  51. package/dist/src/lib/config-updater.js +34 -0
  52. package/dist/src/lib/config-updater.js.map +1 -0
  53. package/dist/src/lib/config.d.ts +53 -0
  54. package/dist/src/lib/config.d.ts.map +1 -0
  55. package/dist/src/lib/config.js +162 -0
  56. package/dist/src/lib/config.js.map +1 -0
  57. package/dist/src/lib/env-sync.d.ts +44 -0
  58. package/dist/src/lib/env-sync.d.ts.map +1 -0
  59. package/dist/src/lib/env-sync.js +207 -0
  60. package/dist/src/lib/env-sync.js.map +1 -0
  61. package/dist/src/lib/logger.d.ts.map +1 -0
  62. package/dist/src/lib/logger.js.map +1 -0
  63. package/dist/src/lib/nx-generator.d.ts +22 -0
  64. package/dist/src/lib/nx-generator.d.ts.map +1 -0
  65. package/dist/src/lib/nx-generator.js +345 -0
  66. package/dist/src/lib/nx-generator.js.map +1 -0
  67. package/dist/src/lib/standalone.d.ts +28 -0
  68. package/dist/src/lib/standalone.d.ts.map +1 -0
  69. package/dist/src/lib/standalone.js +107 -0
  70. package/dist/src/lib/standalone.js.map +1 -0
  71. package/dist/{types → src/types}/index.d.ts +10 -0
  72. package/dist/src/types/index.d.ts.map +1 -0
  73. package/dist/src/types/index.js.map +1 -0
  74. package/dist/src/utils/spinner.d.ts +16 -0
  75. package/dist/src/utils/spinner.d.ts.map +1 -0
  76. package/dist/src/utils/spinner.js +88 -0
  77. package/dist/src/utils/spinner.js.map +1 -0
  78. package/dist/src/utils/validation.d.ts.map +1 -0
  79. package/dist/{utils → src/utils}/validation.js +18 -2
  80. package/dist/src/utils/validation.js.map +1 -0
  81. package/dist/templates/application-additions/.forgecartignore +1 -1
  82. package/dist/templates/application-additions/Procfile +1 -1
  83. package/dist/templates/application-additions/src/app/app.module.ts +16 -0
  84. package/dist/templates/application-additions/src/services/forgecart.service.ts +62 -0
  85. package/dist/templates/application-additions/src/services/index.ts +2 -0
  86. package/dist/templates/application-additions/src/services/product-event-listener.service.ts +150 -0
  87. package/dist/templates/application-e2e-additions/src/support/global-setup.ts +16 -0
  88. package/dist/templates/application-e2e-additions/src/support/test-setup.ts +9 -0
  89. package/dist/templates/storefront-additions/.forgecartignore +30 -6
  90. package/dist/templates/storefront-additions/Procfile +1 -1
  91. package/dist/templates/storefront-additions/package.json +11 -0
  92. package/dist/templates/storefront-additions/postcss.config.js +5 -0
  93. package/dist/templates/storefront-additions/src/app/cart/page.tsx +77 -0
  94. package/dist/templates/storefront-additions/src/app/global.css +1 -0
  95. package/dist/templates/storefront-additions/src/app/layout.tsx +25 -0
  96. package/dist/templates/storefront-additions/src/app/page.tsx +43 -0
  97. package/dist/templates/storefront-additions/src/components/AddToCartButton.tsx +29 -0
  98. package/dist/templates/storefront-additions/src/components/CartItem.tsx +82 -0
  99. package/dist/templates/storefront-additions/src/components/Header.tsx +42 -0
  100. package/dist/templates/storefront-additions/src/components/ProductCard.tsx +57 -0
  101. package/dist/templates/storefront-additions/src/components/QuantitySelector.tsx +35 -0
  102. package/dist/templates/storefront-additions/src/context/CartContext.tsx +158 -0
  103. package/dist/templates/storefront-additions/src/lib/forgecart.ts +19 -8
  104. package/dist/templates/storefront-additions/tailwind.config.js +8 -0
  105. package/dist/templates/storefront-e2e-additions/playwright.config.ts +26 -0
  106. package/dist/templates/storefront-e2e-additions/src/example.spec.ts +11 -0
  107. package/dist/templates/workspace/.nxignore +2 -0
  108. package/package.json +6 -28
  109. package/templates/application-additions/.forgecartignore +1 -1
  110. package/templates/application-additions/Procfile +1 -1
  111. package/templates/application-additions/src/app/app.module.ts +16 -0
  112. package/templates/application-additions/src/services/forgecart.service.ts +62 -0
  113. package/templates/application-additions/src/services/index.ts +2 -0
  114. package/templates/application-additions/src/services/product-event-listener.service.ts +150 -0
  115. package/templates/application-e2e-additions/src/support/global-setup.ts +16 -0
  116. package/templates/application-e2e-additions/src/support/test-setup.ts +9 -0
  117. package/templates/storefront-additions/.forgecartignore +30 -6
  118. package/templates/storefront-additions/Procfile +1 -1
  119. package/templates/storefront-additions/package.json +11 -0
  120. package/templates/storefront-additions/postcss.config.js +5 -0
  121. package/templates/storefront-additions/src/app/cart/page.tsx +77 -0
  122. package/templates/storefront-additions/src/app/global.css +1 -0
  123. package/templates/storefront-additions/src/app/layout.tsx +25 -0
  124. package/templates/storefront-additions/src/app/page.tsx +43 -0
  125. package/templates/storefront-additions/src/components/AddToCartButton.tsx +29 -0
  126. package/templates/storefront-additions/src/components/CartItem.tsx +82 -0
  127. package/templates/storefront-additions/src/components/Header.tsx +42 -0
  128. package/templates/storefront-additions/src/components/ProductCard.tsx +57 -0
  129. package/templates/storefront-additions/src/components/QuantitySelector.tsx +35 -0
  130. package/templates/storefront-additions/src/context/CartContext.tsx +158 -0
  131. package/templates/storefront-additions/src/lib/forgecart.ts +19 -8
  132. package/templates/storefront-additions/tailwind.config.js +8 -0
  133. package/templates/storefront-e2e-additions/playwright.config.ts +26 -0
  134. package/templates/storefront-e2e-additions/src/example.spec.ts +11 -0
  135. package/templates/workspace/.nxignore +2 -0
  136. package/dist/cli.d.ts.map +0 -1
  137. package/dist/cli.js.map +0 -1
  138. package/dist/commands/delete.d.ts.map +0 -1
  139. package/dist/commands/delete.js.map +0 -1
  140. package/dist/commands/deploy.d.ts.map +0 -1
  141. package/dist/commands/deploy.js +0 -128
  142. package/dist/commands/deploy.js.map +0 -1
  143. package/dist/commands/env.d.ts.map +0 -1
  144. package/dist/commands/env.js.map +0 -1
  145. package/dist/commands/init.d.ts.map +0 -1
  146. package/dist/commands/init.js.map +0 -1
  147. package/dist/commands/list.d.ts.map +0 -1
  148. package/dist/commands/list.js.map +0 -1
  149. package/dist/commands/logs.d.ts.map +0 -1
  150. package/dist/commands/logs.js +0 -105
  151. package/dist/commands/logs.js.map +0 -1
  152. package/dist/commands/scale.d.ts.map +0 -1
  153. package/dist/commands/scale.js.map +0 -1
  154. package/dist/commands/status.d.ts.map +0 -1
  155. package/dist/commands/status.js.map +0 -1
  156. package/dist/commands/whoami.d.ts.map +0 -1
  157. package/dist/commands/whoami.js.map +0 -1
  158. package/dist/index.js.map +0 -1
  159. package/dist/lib/api-client.d.ts +0 -21
  160. package/dist/lib/api-client.d.ts.map +0 -1
  161. package/dist/lib/api-client.js +0 -220
  162. package/dist/lib/api-client.js.map +0 -1
  163. package/dist/lib/archive.d.ts.map +0 -1
  164. package/dist/lib/archive.js.map +0 -1
  165. package/dist/lib/config.d.ts +0 -12
  166. package/dist/lib/config.d.ts.map +0 -1
  167. package/dist/lib/config.js +0 -79
  168. package/dist/lib/config.js.map +0 -1
  169. package/dist/lib/logger.d.ts.map +0 -1
  170. package/dist/lib/logger.js.map +0 -1
  171. package/dist/lib/nx-generator.d.ts +0 -8
  172. package/dist/lib/nx-generator.d.ts.map +0 -1
  173. package/dist/lib/nx-generator.js +0 -146
  174. package/dist/lib/nx-generator.js.map +0 -1
  175. package/dist/templates/application-additions/src/services/price-fetcher.service.ts +0 -72
  176. package/dist/templates/storefront-additions/src/app/products/page.tsx +0 -78
  177. package/dist/types/index.d.ts.map +0 -1
  178. package/dist/types/index.js.map +0 -1
  179. package/dist/utils/spinner.d.ts +0 -4
  180. package/dist/utils/spinner.d.ts.map +0 -1
  181. package/dist/utils/spinner.js +0 -20
  182. package/dist/utils/spinner.js.map +0 -1
  183. package/dist/utils/validation.d.ts.map +0 -1
  184. package/dist/utils/validation.js.map +0 -1
  185. package/templates/application-additions/src/services/price-fetcher.service.ts +0 -72
  186. package/templates/storefront-additions/src/app/products/page.tsx +0 -78
  187. /package/dist/{cli.d.ts → src/cli.d.ts} +0 -0
  188. /package/dist/{commands → src/commands}/delete.d.ts +0 -0
  189. /package/dist/{commands → src/commands}/deploy.d.ts +0 -0
  190. /package/dist/{commands → src/commands}/env.d.ts +0 -0
  191. /package/dist/{commands → src/commands}/init.d.ts +0 -0
  192. /package/dist/{commands → src/commands}/list.d.ts +0 -0
  193. /package/dist/{commands → src/commands}/logs.d.ts +0 -0
  194. /package/dist/{commands → src/commands}/scale.d.ts +0 -0
  195. /package/dist/{commands → src/commands}/status.d.ts +0 -0
  196. /package/dist/{commands → src/commands}/whoami.d.ts +0 -0
  197. /package/dist/{index.d.ts → src/index.d.ts} +0 -0
  198. /package/dist/{index.js → src/index.js} +0 -0
  199. /package/dist/{lib → src/lib}/logger.d.ts +0 -0
  200. /package/dist/{lib → src/lib}/logger.js +0 -0
  201. /package/dist/{types → src/types}/index.js +0 -0
  202. /package/dist/{utils → src/utils}/validation.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA6BnC,wBAAgB,iBAAiB,IAAI,OAAO,CAa3C;AAED,wBAAgB,4BAA4B,IAAI,OAAO,CAQtD"}
@@ -3,18 +3,20 @@ import * as fs from 'fs';
3
3
  import inquirer from 'inquirer';
4
4
  import { Command } from 'commander';
5
5
  import logger from '../lib/logger.js';
6
- import { writeConfig, getDefaultConfig, configExists, readConfig, updateConfig, } from '../lib/config.js';
6
+ import { writeConfig, getDefaultConfig, configExists, readConfig, updateConfig, requireAuth, getGlobalApiUrl, } from '../lib/config.js';
7
7
  import { ForgecartApiClient } from '../lib/api-client.js';
8
- import { createNxWorkspace, generateNextApp, generateNestApp, installDependency, copyTemplateFiles, getCliTemplatesDir, } from '../lib/nx-generator.js';
8
+ import { createNxWorkspace, generateNextApp, generateNestApp, installDependency, copyTemplateFiles, getCliTemplatesDir, addPackageScripts, appendEnvPatternsToGitignore, createEnvFile, DEFAULT_NX_VERSION, } from '../lib/nx-generator.js';
9
9
  import { isValidProjectName } from '../utils/validation.js';
10
10
  import { withSpinner } from '../utils/spinner.js';
11
+ import { ensureStandaloneOutput } from '../lib/config-updater.js';
11
12
  export function createInitCommand() {
12
13
  const cmd = new Command('init')
13
- .description('Create a new ForgéCart project')
14
+ .description('Create a new ForgeCart project')
14
15
  .argument('[name]', 'Project name')
15
- .option('-t, --token <token>', 'ForgéCart channel token')
16
+ .option('-t, --token <token>', 'ForgeCart channel token')
16
17
  .option('-a, --application', 'Include NestJS backend application')
17
- .option('--api-url <url>', 'ForgéCart API URL', 'https://api.forgecart.com')
18
+ .option('--api-url <url>', 'ForgeCart API URL', 'https://api.forgecart.com')
19
+ .option('--nx-version <version>', 'NX version to use', DEFAULT_NX_VERSION)
18
20
  .action(async (name, options) => {
19
21
  await initProject(name, options);
20
22
  });
@@ -29,7 +31,9 @@ export function createInitApplicationCommand() {
29
31
  return cmd;
30
32
  }
31
33
  async function initProject(name, options) {
32
- logger.title('ForgéCart Project Setup');
34
+ logger.title('ForgeCart Project Setup');
35
+ // Check authentication first (set by `forgecart login`)
36
+ const authToken = requireAuth();
33
37
  // Prompt for project name if not provided
34
38
  let projectName = name;
35
39
  if (!projectName) {
@@ -68,7 +72,7 @@ async function initProject(name, options) {
68
72
  {
69
73
  type: 'input',
70
74
  name: 'channelToken',
71
- message: 'ForgéCart channel token:',
75
+ message: 'ForgeCart channel token:',
72
76
  validate: (input) => {
73
77
  if (!input)
74
78
  return 'Channel token is required';
@@ -83,8 +87,8 @@ async function initProject(name, options) {
83
87
  logger.error('Channel token is required');
84
88
  process.exit(1);
85
89
  }
86
- const apiUrl = options.apiUrl || 'https://api.forgecart.com';
87
- const apiClient = new ForgecartApiClient(apiUrl, channelToken);
90
+ const apiUrl = options.apiUrl || getGlobalApiUrl();
91
+ const apiClient = new ForgecartApiClient(apiUrl, channelToken, authToken);
88
92
  await withSpinner('Validating channel token...', 'Channel token validated', 'Invalid channel token', async () => {
89
93
  const isValid = await apiClient.validateChannelToken();
90
94
  if (!isValid) {
@@ -106,7 +110,7 @@ async function initProject(name, options) {
106
110
  }
107
111
  // Create NX workspace
108
112
  await withSpinner('Creating NX workspace...', 'NX workspace created', 'Failed to create NX workspace', async () => {
109
- const success = await createNxWorkspace(projectName, process.cwd());
113
+ const success = await createNxWorkspace(projectName, process.cwd(), options.nxVersion);
110
114
  if (!success) {
111
115
  throw new Error('Failed to create NX workspace');
112
116
  }
@@ -120,18 +124,62 @@ async function initProject(name, options) {
120
124
  });
121
125
  // Install @forgecart/sdk
122
126
  await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
123
- const success = await installDependency('@forgecart/sdk', targetDir);
127
+ const success = await installDependency('@forgecart/sdk@^1.2.0', targetDir);
124
128
  if (!success) {
125
129
  throw new Error('Failed to install SDK');
126
130
  }
127
131
  });
132
+ // Install Tailwind CSS
133
+ await withSpinner('Installing Tailwind CSS...', 'Tailwind CSS installed', 'Failed to install Tailwind CSS', async () => {
134
+ const success = await installDependency('tailwindcss @tailwindcss/postcss postcss autoprefixer -D', targetDir);
135
+ if (!success) {
136
+ throw new Error('Failed to install Tailwind CSS');
137
+ }
138
+ });
128
139
  // Copy storefront template additions
129
140
  logger.info('Applying storefront customizations...');
130
141
  const templatesDir = getCliTemplatesDir();
131
142
  const storefrontAdditionsDir = path.join(templatesDir, 'storefront-additions');
132
143
  const storefrontDir = path.join(targetDir, 'apps', 'storefront');
133
144
  copyTemplateFiles(storefrontAdditionsDir, storefrontDir);
145
+ createEnvFile(storefrontDir, 'storefront', {
146
+ channelToken,
147
+ apiUrl,
148
+ });
149
+ // Configure storefront dev port to 4200
150
+ const storefrontProjectJsonPath = path.join(storefrontDir, 'project.json');
151
+ if (fs.existsSync(storefrontProjectJsonPath)) {
152
+ const projectJson = JSON.parse(fs.readFileSync(storefrontProjectJsonPath, 'utf-8'));
153
+ if (!projectJson.targets) {
154
+ projectJson.targets = {};
155
+ }
156
+ if (!projectJson.targets.dev) {
157
+ projectJson.targets.dev = {};
158
+ }
159
+ if (!projectJson.targets.dev.options) {
160
+ projectJson.targets.dev.options = {};
161
+ }
162
+ projectJson.targets.dev.options.port = 4200;
163
+ fs.writeFileSync(storefrontProjectJsonPath, JSON.stringify(projectJson, null, 2));
164
+ logger.debug('Configured storefront dev port to 4200');
165
+ }
134
166
  logger.success('Storefront customizations applied');
167
+ // Copy storefront E2E template additions
168
+ const storefrontE2eAdditionsDir = path.join(templatesDir, 'storefront-e2e-additions');
169
+ const storefrontE2eDir = path.join(targetDir, 'apps', 'storefront-e2e');
170
+ copyTemplateFiles(storefrontE2eAdditionsDir, storefrontE2eDir);
171
+ logger.success('E2E test customizations applied');
172
+ // Add .env patterns to .gitignore
173
+ appendEnvPatternsToGitignore(targetDir);
174
+ // Configure standalone output for deployment
175
+ logger.info('Configuring standalone output...');
176
+ const standaloneConfigured = ensureStandaloneOutput(storefrontDir);
177
+ if (standaloneConfigured) {
178
+ logger.success('Standalone output configured in next.config.js');
179
+ }
180
+ else {
181
+ logger.warn('Could not auto-configure standalone output. Please add output: "standalone" to next.config.js manually.');
182
+ }
135
183
  // Generate NestJS application if requested
136
184
  if (withApplication) {
137
185
  await withSpinner('Generating NestJS application...', 'Application generated', 'Failed to generate application', async () => {
@@ -140,14 +188,32 @@ async function initProject(name, options) {
140
188
  throw new Error('Failed to generate application');
141
189
  }
142
190
  });
191
+ // Install @nestjs/config for environment variable management
192
+ await withSpinner('Installing @nestjs/config...', '@nestjs/config installed', 'Failed to install @nestjs/config', async () => {
193
+ const success = await installDependency('@nestjs/config', targetDir);
194
+ if (!success) {
195
+ throw new Error('Failed to install @nestjs/config');
196
+ }
197
+ });
143
198
  // Copy application template additions
144
199
  logger.info('Applying application customizations...');
145
200
  const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
146
201
  const applicationDir = path.join(targetDir, 'apps', 'application');
147
202
  copyTemplateFiles(applicationAdditionsDir, applicationDir);
203
+ createEnvFile(applicationDir, 'application', {
204
+ channelToken,
205
+ apiUrl,
206
+ });
148
207
  logger.success('Application customizations applied');
208
+ // Copy application E2E template additions
209
+ const applicationE2eAdditionsDir = path.join(templatesDir, 'application-e2e-additions');
210
+ const applicationE2eDir = path.join(targetDir, 'apps', 'application-e2e');
211
+ copyTemplateFiles(applicationE2eAdditionsDir, applicationE2eDir);
212
+ logger.success('Application E2E customizations applied');
149
213
  }
150
- // Create ForgéCart config
214
+ // Add convenience scripts to package.json
215
+ addPackageScripts(targetDir, withApplication || false);
216
+ // Create ForgeCart config (authToken is stored globally in ~/.forgecart/)
151
217
  const config = getDefaultConfig();
152
218
  config.channelToken = channelToken;
153
219
  config.apiUrl = apiUrl;
@@ -157,7 +223,7 @@ async function initProject(name, options) {
157
223
  config.applicationPath = 'apps/application';
158
224
  }
159
225
  writeConfig(config, targetDir);
160
- logger.success('ForgéCart configuration created');
226
+ logger.success('ForgeCart configuration created');
161
227
  // Success message
162
228
  logger.newline();
163
229
  logger.box(`Project "${projectName}" created successfully!
@@ -174,17 +240,20 @@ Your storefront will be available at:
174
240
  Your application will be available at:
175
241
  apps/application/`
176
242
  : ''));
243
+ // Cleanup and exit
244
+ apiClient.dispose();
245
+ process.exit(0);
177
246
  }
178
247
  async function addApplication() {
179
248
  logger.title('Add NestJS Application');
180
- // Check if we're in a ForgéCart project
249
+ // Check if we're in a ForgeCart project
181
250
  if (!configExists()) {
182
- logger.error('Not in a ForgéCart project. Run "forgecart init" first.');
251
+ logger.error('Not in a ForgeCart project. Run "forgecart init" first.');
183
252
  process.exit(1);
184
253
  }
185
254
  const config = readConfig();
186
255
  if (!config) {
187
- logger.error('Invalid ForgéCart configuration');
256
+ logger.error('Invalid ForgeCart configuration');
188
257
  process.exit(1);
189
258
  }
190
259
  // Check if application already exists
@@ -202,18 +271,34 @@ async function addApplication() {
202
271
  });
203
272
  // Install @forgecart/sdk in application
204
273
  await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
205
- const success = await installDependency('@forgecart/sdk', projectRoot);
274
+ const success = await installDependency('@forgecart/sdk@^1.2.0', projectRoot);
206
275
  if (!success) {
207
276
  throw new Error('Failed to install SDK');
208
277
  }
209
278
  });
279
+ // Install @nestjs/config for environment variable management
280
+ await withSpinner('Installing @nestjs/config...', '@nestjs/config installed', 'Failed to install @nestjs/config', async () => {
281
+ const success = await installDependency('@nestjs/config', projectRoot);
282
+ if (!success) {
283
+ throw new Error('Failed to install @nestjs/config');
284
+ }
285
+ });
210
286
  // Copy application template additions
211
287
  logger.info('Applying application customizations...');
212
288
  const templatesDir = getCliTemplatesDir();
213
289
  const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
214
290
  const applicationDir = path.join(projectRoot, 'apps', 'application');
215
291
  copyTemplateFiles(applicationAdditionsDir, applicationDir);
292
+ createEnvFile(applicationDir, 'application', {
293
+ channelToken: config.channelToken,
294
+ apiUrl: config.apiUrl,
295
+ });
216
296
  logger.success('Application customizations applied');
297
+ // Copy application E2E template additions
298
+ const applicationE2eAdditionsDir = path.join(templatesDir, 'application-e2e-additions');
299
+ const applicationE2eDir = path.join(projectRoot, 'apps', 'application-e2e');
300
+ copyTemplateFiles(applicationE2eAdditionsDir, applicationE2eDir);
301
+ logger.success('Application E2E customizations applied');
217
302
  // Update config
218
303
  updateConfig({
219
304
  hasApplication: true,
@@ -229,5 +314,6 @@ Your application is available at:
229
314
  To deploy:
230
315
  cd apps/application
231
316
  forgecart deploy`);
317
+ process.exit(0);
232
318
  }
233
319
  //# 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 @@
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"}
@@ -2,7 +2,7 @@ import { Command } from 'commander';
2
2
  import Table from 'cli-table3';
3
3
  import chalk from 'chalk';
4
4
  import logger from '../lib/logger.js';
5
- import { requireConfig } from '../lib/config.js';
5
+ import { requireConfig, requireAuth } from '../lib/config.js';
6
6
  import { ForgecartApiClient } from '../lib/api-client.js';
7
7
  import { DeploymentStatus } from '../types/index.js';
8
8
  export function createListCommand() {
@@ -31,12 +31,15 @@ function getStatusColor(status) {
31
31
  }
32
32
  }
33
33
  async function listDeployments() {
34
+ // Check authentication first
35
+ const authToken = requireAuth();
34
36
  const config = requireConfig();
35
- const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
37
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken, authToken);
36
38
  const deployments = await apiClient.getDeployments();
37
39
  if (deployments.length === 0) {
38
40
  logger.info('No deployments found');
39
41
  logger.log('Run "forgecart deploy" to deploy your application');
42
+ apiClient.dispose();
40
43
  return;
41
44
  }
42
45
  const table = new Table({
@@ -57,5 +60,6 @@ async function listDeployments() {
57
60
  ]);
58
61
  }
59
62
  console.log(table.toString());
63
+ apiClient.dispose();
60
64
  }
61
65
  //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createLoginCommand(): Command;
3
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA4BnC,wBAAgB,kBAAkB,IAAI,OAAO,CAqB5C"}
@@ -0,0 +1,120 @@
1
+ import { Command } from 'commander';
2
+ import { gql, GraphQLClient } from 'graphql-request';
3
+ import { findProjectRoot, getGlobalConfigPath, updateConfig, updateGlobalConfig, } from '../lib/config.js';
4
+ import logger from '../lib/logger.js';
5
+ import { withSpinner } from '../utils/spinner.js';
6
+ const DEFAULT_API_URL = 'https://api.forgecart.com';
7
+ const DEFAULT_DASHBOARD_URL = 'http://dashboard.forgecart.com';
8
+ export function createLoginCommand() {
9
+ const cmd = new Command('login')
10
+ .description('Authenticate with ForgeCart via browser')
11
+ .option('--api-url <url>', 'API URL', DEFAULT_API_URL)
12
+ .option('--dashboard-url <url>', 'Dashboard URL for authentication', DEFAULT_DASHBOARD_URL)
13
+ .option('--no-browser', 'Skip opening browser automatically')
14
+ .action(async (options) => {
15
+ await browserLogin(options);
16
+ });
17
+ return cmd;
18
+ }
19
+ async function browserLogin(options) {
20
+ const dashboardUrl = options.dashboardUrl.replace(/\/$/, ''); // Remove trailing slash
21
+ const apiUrl = options.apiUrl.replace(/\/$/, ''); // Remove trailing slash
22
+ logger.title('ForgeCart CLI Login');
23
+ logger.newline();
24
+ // Create GraphQL client for admin-api (public endpoints don't require auth)
25
+ const client = new GraphQLClient(`${apiUrl}/admin-api`);
26
+ // 1. Generate device code
27
+ logger.info('Requesting authorization code...');
28
+ const GENERATE_DEVICE_CODE = gql `
29
+ mutation GenerateDeviceCode($input: GenerateDeviceCodeInput!) {
30
+ generateDeviceCode(input: $input) {
31
+ deviceCode
32
+ userCode
33
+ verificationUri
34
+ expiresIn
35
+ }
36
+ }
37
+ `;
38
+ let deviceCodeResponse;
39
+ try {
40
+ const response = await client.request(GENERATE_DEVICE_CODE, { input: { apiUrl } });
41
+ deviceCodeResponse = response.generateDeviceCode;
42
+ }
43
+ catch {
44
+ logger.error('Failed to connect to ForgeCart API');
45
+ logger.error(`Make sure ${apiUrl} is accessible`);
46
+ process.exit(1);
47
+ }
48
+ const { deviceCode, userCode, expiresIn } = deviceCodeResponse;
49
+ // 2. Display instructions - construct auth URL using dashboard URL directly
50
+ const authUrl = `${dashboardUrl}/cli/auth?code=${userCode}`;
51
+ logger.newline();
52
+ logger.info('To authorize, open this URL in your browser:');
53
+ logger.newline();
54
+ logger.info(` ${authUrl}`);
55
+ logger.newline();
56
+ logger.info(`Or enter this code manually: ${userCode}`);
57
+ logger.newline();
58
+ // 3. Open browser (if enabled)
59
+ if (options.browser) {
60
+ try {
61
+ const open = (await import('open')).default;
62
+ await open(authUrl);
63
+ logger.info('Browser opened automatically.');
64
+ }
65
+ catch {
66
+ logger.warn('Could not open browser automatically.');
67
+ }
68
+ }
69
+ // 4. Poll for approval
70
+ logger.newline();
71
+ const result = await withSpinner(`Waiting for approval (code: ${userCode})...`, 'Authorization successful!', 'Authorization failed', () => pollForToken(client, deviceCode, expiresIn));
72
+ // 5. Save auth token to global config (~/.forgecart/)
73
+ updateGlobalConfig({
74
+ authToken: result.authToken,
75
+ apiUrl,
76
+ });
77
+ logger.success(`Global config saved: ${getGlobalConfigPath()}`);
78
+ // 6. Also update project config if in a project (authToken is global only)
79
+ const projectRoot = findProjectRoot(process.cwd());
80
+ if (projectRoot) {
81
+ // Update existing project config with channel token
82
+ updateConfig({
83
+ channelToken: result.channelToken,
84
+ apiUrl,
85
+ }, projectRoot);
86
+ logger.success(`Project config updated: ${projectRoot}/.forgecart/config.json`);
87
+ }
88
+ logger.newline();
89
+ logger.box('Successfully authenticated with ForgeCart!');
90
+ }
91
+ async function pollForToken(client, deviceCode, expiresIn) {
92
+ const POLL_DEVICE_TOKEN = gql `
93
+ query PollDeviceToken($deviceCode: String!) {
94
+ pollDeviceToken(deviceCode: $deviceCode) {
95
+ status
96
+ channelToken
97
+ authToken
98
+ }
99
+ }
100
+ `;
101
+ const startTime = Date.now();
102
+ const pollInterval = 3000; // 3 seconds
103
+ while (Date.now() - startTime < expiresIn * 1000) {
104
+ const response = await client.request(POLL_DEVICE_TOKEN, { deviceCode });
105
+ const { status, channelToken, authToken } = response.pollDeviceToken;
106
+ if (status === 'APPROVED' && channelToken && authToken) {
107
+ return { channelToken, authToken };
108
+ }
109
+ else if (status === 'DENIED') {
110
+ throw new Error('Authorization was denied');
111
+ }
112
+ else if (status === 'EXPIRED') {
113
+ throw new Error('Authorization code expired');
114
+ }
115
+ // Wait before next poll
116
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
117
+ }
118
+ throw new Error('Authorization timed out');
119
+ }
120
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -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,CAc3C"}
@@ -0,0 +1,88 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { requireAuth, requireConfig } from '../lib/config.js';
4
+ import { ForgecartApiClient } from '../lib/api-client.js';
5
+ import logger from '../lib/logger.js';
6
+ import { DeploymentType } from '../types/index.js';
7
+ export function createLogsCommand() {
8
+ const cmd = new Command('logs')
9
+ .description('View deployment logs')
10
+ .argument('[type]', 'Deployment type (storefront or application)', 'storefront')
11
+ .option('-f, --follow', 'Follow log output (default behavior)')
12
+ .action(async (type) => {
13
+ await viewLogs(type);
14
+ });
15
+ return cmd;
16
+ }
17
+ async function viewLogs(type) {
18
+ // Validate type
19
+ if (type !== DeploymentType.STOREFRONT &&
20
+ type !== DeploymentType.APPLICATION) {
21
+ logger.error('Invalid deployment type. Use "storefront" or "application".');
22
+ process.exit(1);
23
+ }
24
+ // Check authentication first
25
+ const authToken = requireAuth();
26
+ const config = requireConfig();
27
+ logger.info(`Connecting to ${type} logs...`);
28
+ // Use ForgecartApiClient with SDK subscription
29
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken, authToken);
30
+ // Handle Ctrl+C
31
+ process.on('SIGINT', () => {
32
+ logger.newline();
33
+ logger.info('Disconnecting...');
34
+ apiClient.dispose();
35
+ process.exit(0);
36
+ });
37
+ try {
38
+ const subscription = apiClient.subscribeToDeploymentLogs(type);
39
+ logger.success(`Connected to ${type} logs`);
40
+ logger.info('Press Ctrl+C to stop');
41
+ logger.newline();
42
+ for await (const result of subscription) {
43
+ const log = result.deploymentLogs;
44
+ if (log) {
45
+ // Try to parse the message as JSON (Epinio format)
46
+ let displayMessage = log.message;
47
+ try {
48
+ const parsed = JSON.parse(log.message);
49
+ // If it's JSON with Message field, use that (or skip if empty)
50
+ if ('Message' in parsed) {
51
+ displayMessage = parsed.Message?.trim() || null;
52
+ }
53
+ }
54
+ catch {
55
+ // Not JSON, use as-is
56
+ }
57
+ // Skip empty messages
58
+ if (!displayMessage) {
59
+ continue;
60
+ }
61
+ // Format timestamp to HH:MM:SS
62
+ const timestamp = new Date(log.timestamp).toLocaleTimeString('en-US', {
63
+ hour12: false,
64
+ hour: '2-digit',
65
+ minute: '2-digit',
66
+ second: '2-digit',
67
+ });
68
+ console.log(`${chalk.gray(timestamp)} ${displayMessage}`);
69
+ }
70
+ }
71
+ }
72
+ catch (error) {
73
+ let errorMessage;
74
+ if (error instanceof Error) {
75
+ errorMessage = error.message;
76
+ }
77
+ else if (typeof error === 'object' && error !== null) {
78
+ errorMessage = JSON.stringify(error, null, 2);
79
+ }
80
+ else {
81
+ errorMessage = String(error);
82
+ }
83
+ logger.error(`Subscription error: ${errorMessage}`);
84
+ apiClient.dispose();
85
+ process.exit(1);
86
+ }
87
+ }
88
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/commands/logs.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -1,6 +1,6 @@
1
1
  import { Command } from 'commander';
2
2
  import logger from '../lib/logger.js';
3
- import { requireConfig } from '../lib/config.js';
3
+ import { requireConfig, requireAuth } from '../lib/config.js';
4
4
  import { ForgecartApiClient } from '../lib/api-client.js';
5
5
  import { DeploymentType } from '../types/index.js';
6
6
  import { withSpinner } from '../utils/spinner.js';
@@ -16,7 +16,8 @@ export function createScaleCommand() {
16
16
  }
17
17
  async function scaleDeployment(type, instances) {
18
18
  // Validate type
19
- if (type !== DeploymentType.STOREFRONT && type !== DeploymentType.APPLICATION) {
19
+ if (type !== DeploymentType.STOREFRONT &&
20
+ type !== DeploymentType.APPLICATION) {
20
21
  logger.error('Invalid deployment type. Use "storefront" or "application".');
21
22
  process.exit(1);
22
23
  }
@@ -25,8 +26,10 @@ async function scaleDeployment(type, instances) {
25
26
  logger.error('Invalid number of instances. Must be between 0 and 10.');
26
27
  process.exit(1);
27
28
  }
29
+ // Check authentication first
30
+ const authToken = requireAuth();
28
31
  const config = requireConfig();
29
- const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
32
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken, authToken);
30
33
  // Check if deployment exists
31
34
  const deployment = await apiClient.getDeployment(type);
32
35
  if (!deployment) {
@@ -41,5 +44,6 @@ async function scaleDeployment(type, instances) {
41
44
  logger.keyValue('Type', scaled.type);
42
45
  logger.keyValue('Instances', scaled.instances.toString());
43
46
  logger.keyValue('Status', scaled.status);
47
+ apiClient.dispose();
44
48
  }
45
49
  //# 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,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC7D,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,CAC5B,IAAoB,EACpB,SAAiB;IAEjB,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,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,6BAA6B;IAC7B,MAAM,SAAS,GAAG,WAAW,EAAE,CAAA;IAE/B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,MAAM,SAAS,GAAG,IAAI,kBAAkB,CACtC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,YAAY,EACnB,SAAS,CACV,CAAA;IAED,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;IACxC,SAAS,CAAC,OAAO,EAAE,CAAA;AACrB,CAAC"}
@@ -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"}
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import logger from '../lib/logger.js';
4
- import { requireConfig } from '../lib/config.js';
4
+ import { requireConfig, requireAuth } from '../lib/config.js';
5
5
  import { ForgecartApiClient } from '../lib/api-client.js';
6
6
  import { DeploymentStatus } from '../types/index.js';
7
7
  import { withSpinner } from '../utils/spinner.js';
@@ -31,8 +31,10 @@ function getStatusColor(status) {
31
31
  }
32
32
  }
33
33
  async function showStatus(type) {
34
+ // Check authentication first
35
+ const authToken = requireAuth();
34
36
  const config = requireConfig();
35
- const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken);
37
+ const apiClient = new ForgecartApiClient(config.apiUrl, config.channelToken, authToken);
36
38
  if (type) {
37
39
  // Show status for specific deployment
38
40
  const deployment = await withSpinner('Fetching deployment status...', 'Status retrieved', 'Failed to fetch status', async () => {
@@ -40,6 +42,7 @@ async function showStatus(type) {
40
42
  });
41
43
  if (!deployment) {
42
44
  logger.error(`No ${type} deployment found`);
45
+ apiClient.dispose();
43
46
  return;
44
47
  }
45
48
  logger.newline();
@@ -63,6 +66,7 @@ async function showStatus(type) {
63
66
  });
64
67
  if (deployments.length === 0) {
65
68
  logger.info('No deployments found');
69
+ apiClient.dispose();
66
70
  return;
67
71
  }
68
72
  for (const deployment of deployments) {
@@ -81,5 +85,6 @@ async function showStatus(type) {
81
85
  }
82
86
  }
83
87
  }
88
+ apiClient.dispose();
84
89
  }
85
90
  //# sourceMappingURL=status.js.map