@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,146 @@
1
+ import { spawn } from 'child_process';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ import logger from './logger.js';
5
+ async function runCommand(command, args, cwd, silent = false) {
6
+ return new Promise((resolve) => {
7
+ const child = spawn(command, args, {
8
+ cwd,
9
+ shell: true,
10
+ stdio: silent ? 'pipe' : 'inherit',
11
+ });
12
+ let output = '';
13
+ let error = '';
14
+ if (silent) {
15
+ child.stdout?.on('data', (data) => {
16
+ output += data.toString();
17
+ });
18
+ child.stderr?.on('data', (data) => {
19
+ error += data.toString();
20
+ });
21
+ }
22
+ child.on('close', (code) => {
23
+ resolve({
24
+ success: code === 0,
25
+ output,
26
+ error,
27
+ });
28
+ });
29
+ child.on('error', (err) => {
30
+ resolve({
31
+ success: false,
32
+ output,
33
+ error: err.message,
34
+ });
35
+ });
36
+ });
37
+ }
38
+ export async function createNxWorkspace(projectName, targetDir) {
39
+ logger.info(`Creating NX workspace: ${projectName}`);
40
+ const result = await runCommand('npx', [
41
+ 'create-nx-workspace@latest',
42
+ projectName,
43
+ '--preset=apps',
44
+ '--nxCloud=skip',
45
+ '--packageManager=npm',
46
+ ], targetDir);
47
+ if (!result.success) {
48
+ logger.error('Failed to create NX workspace');
49
+ return false;
50
+ }
51
+ return true;
52
+ }
53
+ export async function generateNextApp(appName, projectRoot) {
54
+ logger.info(`Generating Next.js application: ${appName}`);
55
+ const result = await runCommand('npx', ['nx', 'g', '@nx/next:application', appName, '--style=css', '--appDir=true'], projectRoot);
56
+ if (!result.success) {
57
+ logger.error('Failed to generate Next.js application');
58
+ return false;
59
+ }
60
+ return true;
61
+ }
62
+ export async function generateNestApp(appName, projectRoot) {
63
+ logger.info(`Generating NestJS application: ${appName}`);
64
+ const result = await runCommand('npx', ['nx', 'g', '@nx/nest:application', appName], projectRoot);
65
+ if (!result.success) {
66
+ logger.error('Failed to generate NestJS application');
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ export async function installDependency(packageName, projectRoot, dev = false) {
72
+ logger.info(`Installing ${packageName}`);
73
+ const args = ['install', packageName];
74
+ if (dev) {
75
+ args.push('--save-dev');
76
+ }
77
+ const result = await runCommand('npm', args, projectRoot);
78
+ if (!result.success) {
79
+ logger.error(`Failed to install ${packageName}`);
80
+ return false;
81
+ }
82
+ return true;
83
+ }
84
+ export async function runNxBuild(appName, projectRoot) {
85
+ logger.info(`Building ${appName}`);
86
+ const result = await runCommand('npx', ['nx', 'build', appName], projectRoot);
87
+ if (!result.success) {
88
+ logger.error(`Failed to build ${appName}`);
89
+ return false;
90
+ }
91
+ return true;
92
+ }
93
+ export function copyTemplateFiles(templateDir, targetDir, overwrite = true) {
94
+ if (!fs.existsSync(templateDir)) {
95
+ return;
96
+ }
97
+ const files = getAllFiles(templateDir);
98
+ for (const file of files) {
99
+ const relativePath = path.relative(templateDir, file);
100
+ const targetPath = path.join(targetDir, relativePath);
101
+ const targetDirPath = path.dirname(targetPath);
102
+ if (!fs.existsSync(targetDirPath)) {
103
+ fs.mkdirSync(targetDirPath, { recursive: true });
104
+ }
105
+ if (overwrite || !fs.existsSync(targetPath)) {
106
+ fs.copyFileSync(file, targetPath);
107
+ logger.debug(`Copied: ${relativePath}`);
108
+ }
109
+ }
110
+ }
111
+ function getAllFiles(dir) {
112
+ const files = [];
113
+ const items = fs.readdirSync(dir, { withFileTypes: true });
114
+ for (const item of items) {
115
+ const fullPath = path.join(dir, item.name);
116
+ if (item.isDirectory()) {
117
+ files.push(...getAllFiles(fullPath));
118
+ }
119
+ else {
120
+ files.push(fullPath);
121
+ }
122
+ }
123
+ return files;
124
+ }
125
+ export function getCliTemplatesDir() {
126
+ // When running from CLI package, templates can be in different locations:
127
+ // 1. Development: apps/cli/templates (relative to src/lib)
128
+ // 2. Installed: dist/templates (relative to dist/lib)
129
+ const currentFileUrl = new URL(import.meta.url);
130
+ const currentFilePath = currentFileUrl.pathname;
131
+ const libDir = path.dirname(currentFilePath);
132
+ // Try dist/templates first (installed package)
133
+ const distTemplatesPath = path.resolve(libDir, '..', 'templates');
134
+ if (fs.existsSync(distTemplatesPath)) {
135
+ return distTemplatesPath;
136
+ }
137
+ // Try apps/cli/templates (development)
138
+ const devTemplatesPath = path.resolve(libDir, '..', '..', 'templates');
139
+ if (fs.existsSync(devTemplatesPath)) {
140
+ return devTemplatesPath;
141
+ }
142
+ // Fallback - try to find templates directory
143
+ logger.warn('Templates directory not found, using fallback path');
144
+ return devTemplatesPath;
145
+ }
146
+ //# sourceMappingURL=nx-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nx-generator.js","sourceRoot":"","sources":["../../src/lib/nx-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ # ForgéCart deployment ignore file
2
+ # Files and directories listed here will not be uploaded during deployment
3
+
4
+ # Dependencies (will be installed during build)
5
+ node_modules/
6
+
7
+ # Development files
8
+ .git/
9
+ .gitignore
10
+ .env
11
+ .env.local
12
+ .env.development
13
+
14
+ # IDE
15
+ .idea/
16
+ .vscode/
17
+ *.swp
18
+ *.swo
19
+
20
+ # Build artifacts (we build on the server)
21
+ dist/
22
+
23
+ # Test files
24
+ __tests__/
25
+ test/
26
+ *.test.ts
27
+ *.spec.ts
28
+ coverage/
29
+
30
+ # Documentation
31
+ README.md
32
+ CHANGELOG.md
33
+ docs/
34
+
35
+ # OS files
36
+ .DS_Store
37
+ Thumbs.db
@@ -0,0 +1 @@
1
+ web: npm run start:prod
@@ -0,0 +1,72 @@
1
+ import { Injectable, OnModuleInit } from '@nestjs/common'
2
+ import { ForgecartClient } from '@forgecart/sdk'
3
+
4
+ // Example service demonstrating ForgéCart SDK integration
5
+ // This can be used for custom backend tasks like:
6
+ // - Scheduled price updates
7
+ // - Inventory synchronization
8
+ // - Custom order processing
9
+ // - Third-party integrations
10
+
11
+ @Injectable()
12
+ export class PriceFetcherService implements OnModuleInit {
13
+ private client: ForgecartClient
14
+
15
+ onModuleInit() {
16
+ this.client = new ForgecartClient({
17
+ channelToken: process.env.FORGECART_CHANNEL_TOKEN || '',
18
+ apiUrl: process.env.FORGECART_API_URL || 'https://api.forgecart.com',
19
+ })
20
+ }
21
+
22
+ async getProductPrices(productIds: string[]): Promise<
23
+ Array<{
24
+ productId: string
25
+ name: string
26
+ price: number
27
+ currencyCode: string
28
+ }>
29
+ > {
30
+ const prices = []
31
+
32
+ for (const productId of productIds) {
33
+ try {
34
+ const product = await this.client.shop.products.get(productId)
35
+ if (product && product.variants?.[0]) {
36
+ prices.push({
37
+ productId,
38
+ name: product.name,
39
+ price: product.variants[0].price,
40
+ currencyCode: product.variants[0].currencyCode,
41
+ })
42
+ }
43
+ } catch (error) {
44
+ console.error(`Failed to fetch price for product ${productId}:`, error)
45
+ }
46
+ }
47
+
48
+ return prices
49
+ }
50
+
51
+ async syncInventory(): Promise<{ synced: number; errors: number }> {
52
+ // Example: Sync inventory with external system
53
+ // This is a placeholder for custom business logic
54
+ let synced = 0
55
+ let errors = 0
56
+
57
+ try {
58
+ const products = await this.client.shop.products.list({ take: 100 })
59
+
60
+ for (const product of products.items || []) {
61
+ // Here you would implement your custom sync logic
62
+ // e.g., update external ERP, sync with warehouse system, etc.
63
+ synced++
64
+ }
65
+ } catch (error) {
66
+ console.error('Inventory sync failed:', error)
67
+ errors++
68
+ }
69
+
70
+ return { synced, errors }
71
+ }
72
+ }
@@ -0,0 +1,40 @@
1
+ # ForgéCart deployment ignore file
2
+ # Files and directories listed here will not be uploaded during deployment
3
+
4
+ # Dependencies (will be installed during build)
5
+ node_modules/
6
+
7
+ # Development files
8
+ .git/
9
+ .gitignore
10
+ .env
11
+ .env.local
12
+ .env.development
13
+ .env.development.local
14
+
15
+ # IDE
16
+ .idea/
17
+ .vscode/
18
+ *.swp
19
+ *.swo
20
+
21
+ # Build artifacts (we build on the server)
22
+ .next/
23
+ out/
24
+
25
+ # Test files
26
+ __tests__/
27
+ *.test.ts
28
+ *.test.tsx
29
+ *.spec.ts
30
+ *.spec.tsx
31
+ coverage/
32
+
33
+ # Documentation
34
+ README.md
35
+ CHANGELOG.md
36
+ docs/
37
+
38
+ # OS files
39
+ .DS_Store
40
+ Thumbs.db
@@ -0,0 +1 @@
1
+ web: npm run start
@@ -0,0 +1,78 @@
1
+ import forgecart from '../../lib/forgecart'
2
+
3
+ // Example product page using ForgéCart SDK
4
+ // This demonstrates how to fetch and display products
5
+
6
+ interface Product {
7
+ id: string
8
+ name: string
9
+ slug: string
10
+ description: string
11
+ featuredAsset?: {
12
+ preview: string
13
+ }
14
+ variants: Array<{
15
+ id: string
16
+ name: string
17
+ price: number
18
+ currencyCode: string
19
+ }>
20
+ }
21
+
22
+ async function getProducts(): Promise<Product[]> {
23
+ try {
24
+ // Fetch products from ForgéCart API
25
+ const result = await forgecart.shop.products.list({
26
+ take: 12,
27
+ })
28
+ return result.items || []
29
+ } catch (error) {
30
+ console.error('Failed to fetch products:', error)
31
+ return []
32
+ }
33
+ }
34
+
35
+ export default async function ProductsPage() {
36
+ const products = await getProducts()
37
+
38
+ return (
39
+ <div className="container mx-auto px-4 py-8">
40
+ <h1 className="text-3xl font-bold mb-8">Products</h1>
41
+
42
+ {products.length === 0 ? (
43
+ <p className="text-gray-600">
44
+ No products found. Make sure your ForgéCart channel is configured correctly.
45
+ </p>
46
+ ) : (
47
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
48
+ {products.map((product) => (
49
+ <div
50
+ key={product.id}
51
+ className="border rounded-lg overflow-hidden shadow-sm hover:shadow-md transition-shadow"
52
+ >
53
+ {product.featuredAsset && (
54
+ <img
55
+ src={product.featuredAsset.preview}
56
+ alt={product.name}
57
+ className="w-full h-48 object-cover"
58
+ />
59
+ )}
60
+ <div className="p-4">
61
+ <h2 className="text-lg font-semibold mb-2">{product.name}</h2>
62
+ <p className="text-gray-600 text-sm mb-3 line-clamp-2">
63
+ {product.description}
64
+ </p>
65
+ {product.variants[0] && (
66
+ <p className="text-lg font-bold text-blue-600">
67
+ {(product.variants[0].price / 100).toFixed(2)}{' '}
68
+ {product.variants[0].currencyCode}
69
+ </p>
70
+ )}
71
+ </div>
72
+ </div>
73
+ ))}
74
+ </div>
75
+ )}
76
+ </div>
77
+ )
78
+ }
@@ -0,0 +1,11 @@
1
+ import { ForgecartClient } from '@forgecart/sdk'
2
+
3
+ // Initialize the ForgéCart SDK client
4
+ // The channel token is read from environment variables
5
+ export const forgecart = new ForgecartClient({
6
+ channelToken: process.env.FORGECART_CHANNEL_TOKEN || '',
7
+ apiUrl: process.env.FORGECART_API_URL || 'https://api.forgecart.com',
8
+ })
9
+
10
+ // Export for use in server components
11
+ export default forgecart
@@ -0,0 +1,70 @@
1
+ export interface ForgecartConfig {
2
+ version: string;
3
+ channelToken: string;
4
+ apiUrl: string;
5
+ hasApplication: boolean;
6
+ storefrontPath: string;
7
+ applicationPath?: string;
8
+ }
9
+ export declare enum DeploymentType {
10
+ STOREFRONT = "storefront",
11
+ APPLICATION = "application"
12
+ }
13
+ export declare enum DeploymentStatus {
14
+ PENDING = "PENDING",
15
+ STAGING = "STAGING",
16
+ RUNNING = "RUNNING",
17
+ ERROR = "ERROR",
18
+ STOPPED = "STOPPED"
19
+ }
20
+ export interface Deployment {
21
+ id: string;
22
+ type: DeploymentType;
23
+ status: DeploymentStatus;
24
+ url: string | null;
25
+ instances: number;
26
+ lastDeployedAt: string | null;
27
+ errorMessage: string | null;
28
+ }
29
+ export interface ChannelInfo {
30
+ id: string;
31
+ code: string;
32
+ }
33
+ export interface DeploymentEnv {
34
+ key: string;
35
+ value: string;
36
+ }
37
+ export interface InitOptions {
38
+ projectName?: string;
39
+ channelToken?: string;
40
+ withApplication?: boolean;
41
+ apiUrl?: string;
42
+ }
43
+ export interface DeployOptions {
44
+ type?: DeploymentType;
45
+ }
46
+ export interface ScaleOptions {
47
+ type: DeploymentType;
48
+ instances: number;
49
+ }
50
+ export interface EnvGetOptions {
51
+ type: DeploymentType;
52
+ }
53
+ export interface EnvSetOptions {
54
+ type: DeploymentType;
55
+ key: string;
56
+ value: string;
57
+ }
58
+ export interface EnvUnsetOptions {
59
+ type: DeploymentType;
60
+ key: string;
61
+ }
62
+ export interface LogsOptions {
63
+ type: DeploymentType;
64
+ follow?: boolean;
65
+ }
66
+ export interface DeleteOptions {
67
+ type: DeploymentType;
68
+ force?: boolean;
69
+ }
70
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,OAAO,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,oBAAY,cAAc;IACxB,UAAU,eAAe;IACzB,WAAW,gBAAgB;CAC5B;AAED,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,cAAc,CAAA;IACpB,MAAM,EAAE,gBAAgB,CAAA;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,cAAc,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB"}
@@ -0,0 +1,14 @@
1
+ export var DeploymentType;
2
+ (function (DeploymentType) {
3
+ DeploymentType["STOREFRONT"] = "storefront";
4
+ DeploymentType["APPLICATION"] = "application";
5
+ })(DeploymentType || (DeploymentType = {}));
6
+ export var DeploymentStatus;
7
+ (function (DeploymentStatus) {
8
+ DeploymentStatus["PENDING"] = "PENDING";
9
+ DeploymentStatus["STAGING"] = "STAGING";
10
+ DeploymentStatus["RUNNING"] = "RUNNING";
11
+ DeploymentStatus["ERROR"] = "ERROR";
12
+ DeploymentStatus["STOPPED"] = "STOPPED";
13
+ })(DeploymentStatus || (DeploymentStatus = {}));
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AASA,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,2CAAyB,CAAA;IACzB,6CAA2B,CAAA;AAC7B,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AAED,MAAM,CAAN,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,uCAAmB,CAAA;IACnB,uCAAmB,CAAA;IACnB,uCAAmB,CAAA;IACnB,mCAAe,CAAA;IACf,uCAAmB,CAAA;AACrB,CAAC,EANW,gBAAgB,KAAhB,gBAAgB,QAM3B"}
@@ -0,0 +1,4 @@
1
+ import { Ora } from 'ora';
2
+ export declare function createSpinner(text: string): Ora;
3
+ export declare function withSpinner<T>(text: string, successText: string, failText: string, fn: () => Promise<T>): Promise<T>;
4
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAK/C;AAED,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAWZ"}
@@ -0,0 +1,20 @@
1
+ import ora from 'ora';
2
+ export function createSpinner(text) {
3
+ return ora({
4
+ text,
5
+ spinner: 'dots',
6
+ });
7
+ }
8
+ export async function withSpinner(text, successText, failText, fn) {
9
+ const spinner = createSpinner(text).start();
10
+ try {
11
+ const result = await fn();
12
+ spinner.succeed(successText);
13
+ return result;
14
+ }
15
+ catch (error) {
16
+ spinner.fail(failText);
17
+ throw error;
18
+ }
19
+ }
20
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/utils/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,GAAY,MAAM,KAAK,CAAA;AAE9B,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,GAAG,CAAC;QACT,IAAI;QACJ,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,WAAmB,EACnB,QAAgB,EAChB,EAAoB;IAEpB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAA;IAE3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;QACzB,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC5B,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtB,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { DeploymentType } from '../types/index.js';
2
+ export declare function isValidProjectName(name: string): boolean;
3
+ export declare function detectProjectType(dir: string): DeploymentType | null;
4
+ export declare function validateChannelToken(token: string): boolean;
5
+ export declare function isNxWorkspace(dir: string): boolean;
6
+ export declare function hasStorefront(projectRoot: string, storefrontPath: string): boolean;
7
+ export declare function hasApplication(projectRoot: string, applicationPath: string): boolean;
8
+ export declare function getCurrentAppDir(projectRoot: string): {
9
+ type: DeploymentType;
10
+ path: string;
11
+ } | null;
12
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAiCpE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAGlF;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAGpF;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IACrD,IAAI,EAAE,cAAc,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,IAAI,CAcP"}
@@ -0,0 +1,66 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { DeploymentType } from '../types/index.js';
4
+ export function isValidProjectName(name) {
5
+ // Must start with letter, can contain letters, numbers, hyphens
6
+ return /^[a-z][a-z0-9-]*$/.test(name);
7
+ }
8
+ export function detectProjectType(dir) {
9
+ // Check for Next.js project
10
+ const nextConfig = path.join(dir, 'next.config.js');
11
+ const nextConfigMjs = path.join(dir, 'next.config.mjs');
12
+ if (fs.existsSync(nextConfig) || fs.existsSync(nextConfigMjs)) {
13
+ return DeploymentType.STOREFRONT;
14
+ }
15
+ // Check for NestJS project
16
+ const nestCliJson = path.join(dir, 'nest-cli.json');
17
+ if (fs.existsSync(nestCliJson)) {
18
+ return DeploymentType.APPLICATION;
19
+ }
20
+ // Check package.json for hints
21
+ const packageJson = path.join(dir, 'package.json');
22
+ if (fs.existsSync(packageJson)) {
23
+ try {
24
+ const pkg = JSON.parse(fs.readFileSync(packageJson, 'utf-8'));
25
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
26
+ if (deps['next']) {
27
+ return DeploymentType.STOREFRONT;
28
+ }
29
+ if (deps['@nestjs/core']) {
30
+ return DeploymentType.APPLICATION;
31
+ }
32
+ }
33
+ catch {
34
+ // Ignore parse errors
35
+ }
36
+ }
37
+ return null;
38
+ }
39
+ export function validateChannelToken(token) {
40
+ // Basic validation - tokens should be non-empty strings
41
+ return typeof token === 'string' && token.length > 0;
42
+ }
43
+ export function isNxWorkspace(dir) {
44
+ return fs.existsSync(path.join(dir, 'nx.json'));
45
+ }
46
+ export function hasStorefront(projectRoot, storefrontPath) {
47
+ const fullPath = path.join(projectRoot, storefrontPath);
48
+ return fs.existsSync(fullPath) && detectProjectType(fullPath) === DeploymentType.STOREFRONT;
49
+ }
50
+ export function hasApplication(projectRoot, applicationPath) {
51
+ const fullPath = path.join(projectRoot, applicationPath);
52
+ return fs.existsSync(fullPath) && detectProjectType(fullPath) === DeploymentType.APPLICATION;
53
+ }
54
+ export function getCurrentAppDir(projectRoot) {
55
+ const cwd = process.cwd();
56
+ // Check if we're in apps/storefront
57
+ if (cwd.includes(path.join(projectRoot, 'apps', 'storefront'))) {
58
+ return { type: DeploymentType.STOREFRONT, path: cwd };
59
+ }
60
+ // Check if we're in apps/application
61
+ if (cwd.includes(path.join(projectRoot, 'apps', 'application'))) {
62
+ return { type: DeploymentType.APPLICATION, path: cwd };
63
+ }
64
+ return null;
65
+ }
66
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}