@forgecart/cli 1.0.1 → 2.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.
- package/dist/bin/forgecart.d.ts +2 -0
- package/dist/bin/forgecart.js +4 -0
- package/dist/bin/forgecart.js.map +1 -0
- package/dist/src/cli.d.ts +14 -1
- package/dist/src/cli.js +30 -15
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/init.d.ts +20 -2
- package/dist/src/commands/init.js +88 -255
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/placeholders.d.ts +19 -0
- package/dist/src/commands/placeholders.js +109 -0
- package/dist/src/commands/placeholders.js.map +1 -0
- package/dist/src/output.d.ts +11 -0
- package/dist/src/output.js +16 -0
- package/dist/src/output.js.map +1 -0
- package/package.json +21 -11
- package/templates/storefront/.env.example +12 -0
- package/templates/storefront/.forgecartignore +2 -0
- package/templates/storefront/Procfile +1 -0
- package/templates/storefront/README.md +87 -0
- package/templates/storefront/next.config.js +14 -0
- package/templates/storefront/package.json +25 -0
- package/templates/storefront/postcss.config.js +6 -0
- package/templates/storefront/src/app/cart/page.tsx +110 -0
- package/templates/storefront/src/app/globals.css +13 -0
- package/templates/storefront/src/app/layout.tsx +30 -0
- package/templates/storefront/src/app/page.tsx +49 -0
- package/templates/storefront/src/app/products/[slug]/not-found.tsx +20 -0
- package/templates/storefront/src/app/products/[slug]/page.tsx +96 -0
- package/templates/storefront/src/app/products/page.tsx +27 -0
- package/templates/storefront/src/components/AddToCartButton.tsx +30 -0
- package/templates/storefront/src/components/Header.tsx +36 -0
- package/templates/storefront/src/components/ProductCard.tsx +43 -0
- package/templates/storefront/src/lib/cart-context.tsx +116 -0
- package/templates/storefront/src/lib/forgecart.ts +202 -0
- package/templates/storefront/tailwind.config.js +8 -0
- package/templates/storefront/tsconfig.json +23 -0
- package/LICENSE +0 -21
- package/README.md +0 -179
- package/bin/forgecart.js +0 -3
- package/dist/package.json +0 -49
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/commands/delete.d.ts +0 -3
- package/dist/src/commands/delete.d.ts.map +0 -1
- package/dist/src/commands/delete.js +0 -58
- package/dist/src/commands/delete.js.map +0 -1
- package/dist/src/commands/deploy.d.ts +0 -3
- package/dist/src/commands/deploy.d.ts.map +0 -1
- package/dist/src/commands/deploy.js +0 -235
- package/dist/src/commands/deploy.js.map +0 -1
- package/dist/src/commands/env.d.ts +0 -3
- package/dist/src/commands/env.d.ts.map +0 -1
- package/dist/src/commands/env.js +0 -151
- package/dist/src/commands/env.js.map +0 -1
- package/dist/src/commands/init.d.ts.map +0 -1
- package/dist/src/commands/list.d.ts +0 -3
- package/dist/src/commands/list.d.ts.map +0 -1
- package/dist/src/commands/list.js +0 -63
- package/dist/src/commands/list.js.map +0 -1
- package/dist/src/commands/login.d.ts +0 -3
- package/dist/src/commands/login.d.ts.map +0 -1
- package/dist/src/commands/login.js +0 -120
- package/dist/src/commands/login.js.map +0 -1
- package/dist/src/commands/logs.d.ts +0 -3
- package/dist/src/commands/logs.d.ts.map +0 -1
- package/dist/src/commands/logs.js +0 -88
- package/dist/src/commands/logs.js.map +0 -1
- package/dist/src/commands/scale.d.ts +0 -3
- package/dist/src/commands/scale.d.ts.map +0 -1
- package/dist/src/commands/scale.js +0 -48
- package/dist/src/commands/scale.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -3
- package/dist/src/commands/status.d.ts.map +0 -1
- package/dist/src/commands/status.js +0 -87
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/commands/whoami.d.ts +0 -3
- package/dist/src/commands/whoami.d.ts.map +0 -1
- package/dist/src/commands/whoami.js +0 -57
- package/dist/src/commands/whoami.js.map +0 -1
- package/dist/src/index.d.ts +0 -3
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -5
- package/dist/src/index.js.map +0 -1
- package/dist/src/lib/api-client.d.ts +0 -28
- package/dist/src/lib/api-client.d.ts.map +0 -1
- package/dist/src/lib/api-client.js +0 -137
- package/dist/src/lib/api-client.js.map +0 -1
- package/dist/src/lib/archive.d.ts +0 -9
- package/dist/src/lib/archive.d.ts.map +0 -1
- package/dist/src/lib/archive.js +0 -118
- package/dist/src/lib/archive.js.map +0 -1
- package/dist/src/lib/config-updater.d.ts +0 -10
- package/dist/src/lib/config-updater.d.ts.map +0 -1
- package/dist/src/lib/config-updater.js +0 -34
- package/dist/src/lib/config-updater.js.map +0 -1
- package/dist/src/lib/config.d.ts +0 -53
- package/dist/src/lib/config.d.ts.map +0 -1
- package/dist/src/lib/config.js +0 -162
- package/dist/src/lib/config.js.map +0 -1
- package/dist/src/lib/env-sync.d.ts +0 -36
- package/dist/src/lib/env-sync.d.ts.map +0 -1
- package/dist/src/lib/env-sync.js +0 -118
- package/dist/src/lib/env-sync.js.map +0 -1
- package/dist/src/lib/logger.d.ts +0 -15
- package/dist/src/lib/logger.d.ts.map +0 -1
- package/dist/src/lib/logger.js +0 -54
- package/dist/src/lib/logger.js.map +0 -1
- package/dist/src/lib/nx-generator.d.ts +0 -20
- package/dist/src/lib/nx-generator.d.ts.map +0 -1
- package/dist/src/lib/nx-generator.js +0 -338
- package/dist/src/lib/nx-generator.js.map +0 -1
- package/dist/src/lib/standalone.d.ts +0 -28
- package/dist/src/lib/standalone.d.ts.map +0 -1
- package/dist/src/lib/standalone.js +0 -107
- package/dist/src/lib/standalone.js.map +0 -1
- package/dist/src/types/index.d.ts +0 -80
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/index.js +0 -14
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/utils/spinner.d.ts +0 -4
- package/dist/src/utils/spinner.d.ts.map +0 -1
- package/dist/src/utils/spinner.js +0 -20
- package/dist/src/utils/spinner.js.map +0 -1
- package/dist/src/utils/validation.d.ts +0 -12
- package/dist/src/utils/validation.d.ts.map +0 -1
- package/dist/src/utils/validation.js +0 -82
- package/dist/src/utils/validation.js.map +0 -1
- package/dist/templates/application-additions/.forgecartignore +0 -37
- package/dist/templates/application-additions/Procfile +0 -1
- package/dist/templates/application-additions/env.example +0 -7
- package/dist/templates/application-additions/src/app/app.module.ts +0 -16
- package/dist/templates/application-additions/src/services/forgecart.service.ts +0 -62
- package/dist/templates/application-additions/src/services/index.ts +0 -2
- package/dist/templates/application-additions/src/services/price-fetcher.service.ts +0 -71
- package/dist/templates/storefront-additions/.forgecartignore +0 -64
- package/dist/templates/storefront-additions/Procfile +0 -1
- package/dist/templates/storefront-additions/env.example +0 -3
- package/dist/templates/storefront-additions/package.json +0 -11
- package/dist/templates/storefront-additions/src/app/products/page.tsx +0 -66
- package/dist/templates/storefront-additions/src/lib/forgecart.ts +0 -22
- package/dist/templates/workspace/.nxignore +0 -2
- package/templates/application-additions/.forgecartignore +0 -37
- package/templates/application-additions/Procfile +0 -1
- package/templates/application-additions/env.example +0 -7
- package/templates/application-additions/src/app/app.module.ts +0 -16
- package/templates/application-additions/src/services/forgecart.service.ts +0 -62
- package/templates/application-additions/src/services/index.ts +0 -2
- package/templates/application-additions/src/services/price-fetcher.service.ts +0 -71
- package/templates/storefront-additions/.forgecartignore +0 -64
- package/templates/storefront-additions/Procfile +0 -1
- package/templates/storefront-additions/env.example +0 -3
- package/templates/storefront-additions/package.json +0 -11
- package/templates/storefront-additions/src/app/products/page.tsx +0 -66
- package/templates/storefront-additions/src/lib/forgecart.ts +0 -22
- package/templates/workspace/.nxignore +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forgecart.js","sourceRoot":"","sources":["../../bin/forgecart.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,KAAK,GAAG,EAAE,CAAC"}
|
package/dist/src/cli.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
/** CLI version, kept in sync with `package.json`. */
|
|
3
|
+
export declare const CLI_VERSION = "2.0.0";
|
|
4
|
+
/**
|
|
5
|
+
* Build the `forgecart` commander program with the full command surface.
|
|
6
|
+
*
|
|
7
|
+
* `init` is fully implemented; the remaining commands are registered with their
|
|
8
|
+
* exact options/arguments but announce that they arrive with the publish
|
|
9
|
+
* pipeline.
|
|
10
|
+
*/
|
|
2
11
|
export declare function createProgram(): Command;
|
|
3
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Parse argv and execute the program. Any thrown error is surfaced on stderr and
|
|
14
|
+
* the process exits with a non-zero status. Errors are never swallowed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function run(argv?: string[]): Promise<void>;
|
package/dist/src/cli.js
CHANGED
|
@@ -1,32 +1,47 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
3
|
-
import { createDeployCommand } from './commands/
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import { createInitCommand } from './commands/init.js';
|
|
3
|
+
import { createDeleteCommand, createDeployCommand, createEnvCommand, createInitApplicationCommand, createListCommand, createLogsCommand, createScaleCommand, createStatusCommand, createWhoamiCommand, } from './commands/placeholders.js';
|
|
4
|
+
import { printError } from './output.js';
|
|
5
|
+
/** CLI version, kept in sync with `package.json`. */
|
|
6
|
+
export const CLI_VERSION = '2.0.0';
|
|
7
|
+
/**
|
|
8
|
+
* Build the `forgecart` commander program with the full command surface.
|
|
9
|
+
*
|
|
10
|
+
* `init` is fully implemented; the remaining commands are registered with their
|
|
11
|
+
* exact options/arguments but announce that they arrive with the publish
|
|
12
|
+
* pipeline.
|
|
13
|
+
*/
|
|
12
14
|
export function createProgram() {
|
|
13
15
|
const program = new Command();
|
|
14
16
|
program
|
|
15
17
|
.name('forgecart')
|
|
16
|
-
.description('CLI
|
|
17
|
-
.version(
|
|
18
|
-
// Add commands
|
|
19
|
-
program.addCommand(createLoginCommand());
|
|
18
|
+
.description('CLI for scaffolding and operating ForgeCart channel storefronts')
|
|
19
|
+
.version(CLI_VERSION);
|
|
20
20
|
program.addCommand(createInitCommand());
|
|
21
21
|
program.addCommand(createInitApplicationCommand());
|
|
22
22
|
program.addCommand(createDeployCommand());
|
|
23
23
|
program.addCommand(createListCommand());
|
|
24
24
|
program.addCommand(createStatusCommand());
|
|
25
|
+
program.addCommand(createLogsCommand());
|
|
25
26
|
program.addCommand(createDeleteCommand());
|
|
26
27
|
program.addCommand(createScaleCommand());
|
|
27
28
|
program.addCommand(createEnvCommand());
|
|
28
|
-
program.addCommand(createLogsCommand());
|
|
29
29
|
program.addCommand(createWhoamiCommand());
|
|
30
30
|
return program;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse argv and execute the program. Any thrown error is surfaced on stderr and
|
|
34
|
+
* the process exits with a non-zero status. Errors are never swallowed.
|
|
35
|
+
*/
|
|
36
|
+
export async function run(argv = process.argv) {
|
|
37
|
+
const program = createProgram();
|
|
38
|
+
try {
|
|
39
|
+
await program.parseAsync(argv);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
printError(`Error: ${message}`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
32
47
|
//# sourceMappingURL=cli.js.map
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,qDAAqD;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,WAAW,CAAC;SACjB,WAAW,CAAC,iEAAiE,CAAC;SAC9E,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,4BAA4B,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAE1C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAiB,OAAO,CAAC,IAAI;IACrD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,UAAU,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QAChC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
/** Default shop API base. Overridable via `--api-url`. */
|
|
3
|
+
export declare const DEFAULT_SHOP_API_URL = "https://api.forgecart.com";
|
|
4
|
+
/** Resolved options for `forgecart init`. */
|
|
5
|
+
export interface InitOptions {
|
|
6
|
+
/** Channel token (required). */
|
|
7
|
+
token?: string;
|
|
8
|
+
/** Shop API base URL. */
|
|
9
|
+
apiUrl: string;
|
|
10
|
+
/** Whether to also scaffold a NestJS application (planned for a later phase). */
|
|
11
|
+
application?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Run `forgecart init`.
|
|
15
|
+
*
|
|
16
|
+
* Resolves the target directory, copies the bundled storefront template into it,
|
|
17
|
+
* writes the ForgeCart config and `.env.local`, then prints next steps. Throws a
|
|
18
|
+
* clear Error on any failure (missing token, missing template, copy failure).
|
|
19
|
+
*/
|
|
20
|
+
export declare function runInit(name: string | undefined, options: InitOptions): Promise<void>;
|
|
21
|
+
/** Build the `init [name]` command. */
|
|
2
22
|
export declare function createInitCommand(): Command;
|
|
3
|
-
export declare function createInitApplicationCommand(): Command;
|
|
4
|
-
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1,267 +1,100 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { mkdir, cp, writeFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { Command } from 'commander';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.option('-a, --application', 'Include NestJS backend application')
|
|
18
|
-
.option('--api-url <url>', 'ForgeCart API URL', 'https://api.forgecart.com')
|
|
19
|
-
.option('--nx-version <version>', 'NX version to use', DEFAULT_NX_VERSION)
|
|
20
|
-
.action(async (name, options) => {
|
|
21
|
-
await initProject(name, options);
|
|
22
|
-
});
|
|
23
|
-
return cmd;
|
|
5
|
+
import { print } from '../output.js';
|
|
6
|
+
/** Default shop API base. Overridable via `--api-url`. */
|
|
7
|
+
export const DEFAULT_SHOP_API_URL = 'https://api.forgecart.com';
|
|
8
|
+
/**
|
|
9
|
+
* Absolute path to the bundled storefront scaffold.
|
|
10
|
+
*
|
|
11
|
+
* At runtime this file lives at `<pkg>/dist/src/commands/init.js`, so the
|
|
12
|
+
* `templates/` directory shipped alongside `dist/` is three levels up.
|
|
13
|
+
*/
|
|
14
|
+
function getStorefrontTemplateDir() {
|
|
15
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
return resolve(here, '..', '..', '..', 'templates', 'storefront');
|
|
24
17
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
return cmd;
|
|
32
|
-
}
|
|
33
|
-
async function initProject(name, options) {
|
|
34
|
-
logger.title('ForgeCart Project Setup');
|
|
35
|
-
// Check authentication first (set by `forgecart login`)
|
|
36
|
-
const authToken = requireAuth();
|
|
37
|
-
// Prompt for project name if not provided
|
|
38
|
-
let projectName = name;
|
|
39
|
-
if (!projectName) {
|
|
40
|
-
const answers = await inquirer.prompt([
|
|
41
|
-
{
|
|
42
|
-
type: 'input',
|
|
43
|
-
name: 'projectName',
|
|
44
|
-
message: 'Project name:',
|
|
45
|
-
validate: (input) => {
|
|
46
|
-
if (!input)
|
|
47
|
-
return 'Project name is required';
|
|
48
|
-
if (!isValidProjectName(input)) {
|
|
49
|
-
return 'Project name must start with a letter and contain only lowercase letters, numbers, and hyphens';
|
|
50
|
-
}
|
|
51
|
-
return true;
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
]);
|
|
55
|
-
projectName = answers.projectName;
|
|
56
|
-
}
|
|
57
|
-
// Validate project name
|
|
58
|
-
if (!projectName || !isValidProjectName(projectName)) {
|
|
59
|
-
logger.error('Invalid project name. Must start with a letter and contain only lowercase letters, numbers, and hyphens.');
|
|
60
|
-
process.exit(1);
|
|
18
|
+
/** True if the path exists and is a directory. */
|
|
19
|
+
async function isDirectory(path) {
|
|
20
|
+
try {
|
|
21
|
+
const info = await stat(path);
|
|
22
|
+
return info.isDirectory();
|
|
61
23
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (fs.existsSync(targetDir)) {
|
|
65
|
-
logger.error(`Directory ${projectName} already exists`);
|
|
66
|
-
process.exit(1);
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
67
26
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
27
|
+
}
|
|
28
|
+
/** Build the `.forgecart/config.json` payload. */
|
|
29
|
+
function buildConfig(channelToken, options) {
|
|
30
|
+
return {
|
|
31
|
+
version: '2.0',
|
|
32
|
+
channelToken,
|
|
33
|
+
apiUrl: options.apiUrl,
|
|
34
|
+
hasApplication: options.application ?? false,
|
|
35
|
+
storefrontPath: '.',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Build the `.env.local` contents for the storefront SDK client. */
|
|
39
|
+
function buildEnvLocal(channelToken, apiUrl) {
|
|
40
|
+
return [
|
|
41
|
+
`FORGECART_CHANNEL_TOKEN=${channelToken}`,
|
|
42
|
+
`FORGECART_SHOP_API_URL=${apiUrl}`,
|
|
43
|
+
'',
|
|
44
|
+
].join('\n');
|
|
45
|
+
}
|
|
46
|
+
/** Print the post-scaffold next steps. */
|
|
47
|
+
function printNextSteps(targetDir, application) {
|
|
48
|
+
print('');
|
|
49
|
+
print('Storefront scaffolded successfully.');
|
|
50
|
+
print('');
|
|
51
|
+
print('Next steps:');
|
|
52
|
+
print(` cd ${targetDir}`);
|
|
53
|
+
print(' npm install');
|
|
54
|
+
print(' npm run dev');
|
|
55
|
+
print('');
|
|
56
|
+
if (application) {
|
|
57
|
+
print('Note: --application was requested. A NestJS application scaffold arrives ' +
|
|
58
|
+
'in a later phase (TODO).');
|
|
59
|
+
print('');
|
|
84
60
|
}
|
|
85
|
-
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Run `forgecart init`.
|
|
64
|
+
*
|
|
65
|
+
* Resolves the target directory, copies the bundled storefront template into it,
|
|
66
|
+
* writes the ForgeCart config and `.env.local`, then prints next steps. Throws a
|
|
67
|
+
* clear Error on any failure (missing token, missing template, copy failure).
|
|
68
|
+
*/
|
|
69
|
+
export async function runInit(name, options) {
|
|
70
|
+
const channelToken = options.token?.trim();
|
|
86
71
|
if (!channelToken) {
|
|
87
|
-
|
|
88
|
-
process.exit(1);
|
|
72
|
+
throw new Error('A channel token is required. Pass it with --token <token> (or -t <token>).');
|
|
89
73
|
}
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (!isValid) {
|
|
95
|
-
throw new Error('Invalid channel token');
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
// Prompt for application inclusion if not specified
|
|
99
|
-
let withApplication = options.withApplication;
|
|
100
|
-
if (withApplication === undefined) {
|
|
101
|
-
const answers = await inquirer.prompt([
|
|
102
|
-
{
|
|
103
|
-
type: 'confirm',
|
|
104
|
-
name: 'withApplication',
|
|
105
|
-
message: 'Include NestJS backend application?',
|
|
106
|
-
default: false,
|
|
107
|
-
},
|
|
108
|
-
]);
|
|
109
|
-
withApplication = answers.withApplication;
|
|
74
|
+
const targetDir = name ? resolve(process.cwd(), name) : process.cwd();
|
|
75
|
+
const templateDir = getStorefrontTemplateDir();
|
|
76
|
+
if (!(await isDirectory(templateDir))) {
|
|
77
|
+
throw new Error(`Storefront template not found at ${templateDir}.`);
|
|
110
78
|
}
|
|
111
|
-
|
|
112
|
-
await
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
await withSpinner('Generating Next.js storefront...', 'Storefront generated', 'Failed to generate storefront', async () => {
|
|
120
|
-
const success = await generateNextApp('storefront', targetDir);
|
|
121
|
-
if (!success) {
|
|
122
|
-
throw new Error('Failed to generate storefront');
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
// Install @forgecart/sdk
|
|
126
|
-
await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
|
|
127
|
-
const success = await installDependency('@forgecart/sdk@^1.2.0', targetDir);
|
|
128
|
-
if (!success) {
|
|
129
|
-
throw new Error('Failed to install SDK');
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
// Copy storefront template additions
|
|
133
|
-
logger.info('Applying storefront customizations...');
|
|
134
|
-
const templatesDir = getCliTemplatesDir();
|
|
135
|
-
const storefrontAdditionsDir = path.join(templatesDir, 'storefront-additions');
|
|
136
|
-
const storefrontDir = path.join(targetDir, 'apps', 'storefront');
|
|
137
|
-
copyTemplateFiles(storefrontAdditionsDir, storefrontDir);
|
|
138
|
-
renameEnvExample(storefrontDir);
|
|
139
|
-
logger.success('Storefront customizations applied');
|
|
140
|
-
// Add .env patterns to .gitignore
|
|
141
|
-
appendEnvPatternsToGitignore(targetDir);
|
|
142
|
-
// Configure standalone output for deployment
|
|
143
|
-
logger.info('Configuring standalone output...');
|
|
144
|
-
const standaloneConfigured = ensureStandaloneOutput(storefrontDir);
|
|
145
|
-
if (standaloneConfigured) {
|
|
146
|
-
logger.success('Standalone output configured in next.config.js');
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
logger.warn('Could not auto-configure standalone output. Please add output: "standalone" to next.config.js manually.');
|
|
150
|
-
}
|
|
151
|
-
// Generate NestJS application if requested
|
|
152
|
-
if (withApplication) {
|
|
153
|
-
await withSpinner('Generating NestJS application...', 'Application generated', 'Failed to generate application', async () => {
|
|
154
|
-
const success = await generateNestApp('application', targetDir);
|
|
155
|
-
if (!success) {
|
|
156
|
-
throw new Error('Failed to generate application');
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
// Install @nestjs/config for environment variable management
|
|
160
|
-
await withSpinner('Installing @nestjs/config...', '@nestjs/config installed', 'Failed to install @nestjs/config', async () => {
|
|
161
|
-
const success = await installDependency('@nestjs/config', targetDir);
|
|
162
|
-
if (!success) {
|
|
163
|
-
throw new Error('Failed to install @nestjs/config');
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
// Copy application template additions
|
|
167
|
-
logger.info('Applying application customizations...');
|
|
168
|
-
const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
|
|
169
|
-
const applicationDir = path.join(targetDir, 'apps', 'application');
|
|
170
|
-
copyTemplateFiles(applicationAdditionsDir, applicationDir);
|
|
171
|
-
renameEnvExample(applicationDir);
|
|
172
|
-
logger.success('Application customizations applied');
|
|
173
|
-
}
|
|
174
|
-
// Add convenience scripts to package.json
|
|
175
|
-
addPackageScripts(targetDir, withApplication || false);
|
|
176
|
-
// Create ForgeCart config (authToken is stored globally in ~/.forgecart/)
|
|
177
|
-
const config = getDefaultConfig();
|
|
178
|
-
config.channelToken = channelToken;
|
|
179
|
-
config.apiUrl = apiUrl;
|
|
180
|
-
config.hasApplication = withApplication || false;
|
|
181
|
-
config.storefrontPath = 'apps/storefront';
|
|
182
|
-
if (withApplication) {
|
|
183
|
-
config.applicationPath = 'apps/application';
|
|
184
|
-
}
|
|
185
|
-
writeConfig(config, targetDir);
|
|
186
|
-
logger.success('ForgeCart configuration created');
|
|
187
|
-
// Success message
|
|
188
|
-
logger.newline();
|
|
189
|
-
logger.box(`Project "${projectName}" created successfully!
|
|
190
|
-
|
|
191
|
-
Next steps:
|
|
192
|
-
cd ${projectName}
|
|
193
|
-
forgecart deploy
|
|
194
|
-
|
|
195
|
-
Your storefront will be available at:
|
|
196
|
-
apps/storefront/` +
|
|
197
|
-
(withApplication
|
|
198
|
-
? `
|
|
199
|
-
|
|
200
|
-
Your application will be available at:
|
|
201
|
-
apps/application/`
|
|
202
|
-
: ''));
|
|
79
|
+
await mkdir(targetDir, { recursive: true });
|
|
80
|
+
await cp(templateDir, targetDir, { recursive: true });
|
|
81
|
+
const configDir = join(targetDir, '.forgecart');
|
|
82
|
+
await mkdir(configDir, { recursive: true });
|
|
83
|
+
const config = buildConfig(channelToken, options);
|
|
84
|
+
await writeFile(join(configDir, 'config.json'), `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
85
|
+
await writeFile(join(targetDir, '.env.local'), buildEnvLocal(channelToken, options.apiUrl), 'utf8');
|
|
86
|
+
printNextSteps(name ?? '.', config.hasApplication);
|
|
203
87
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
// Check if application already exists
|
|
217
|
-
if (config.hasApplication) {
|
|
218
|
-
logger.error('Application already exists in this project');
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
const projectRoot = process.cwd();
|
|
222
|
-
// Generate NestJS application
|
|
223
|
-
await withSpinner('Generating NestJS application...', 'Application generated', 'Failed to generate application', async () => {
|
|
224
|
-
const success = await generateNestApp('application', projectRoot);
|
|
225
|
-
if (!success) {
|
|
226
|
-
throw new Error('Failed to generate application');
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
// Install @forgecart/sdk in application
|
|
230
|
-
await withSpinner('Installing @forgecart/sdk...', '@forgecart/sdk installed', 'Failed to install SDK', async () => {
|
|
231
|
-
const success = await installDependency('@forgecart/sdk@^1.2.0', projectRoot);
|
|
232
|
-
if (!success) {
|
|
233
|
-
throw new Error('Failed to install SDK');
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
// Install @nestjs/config for environment variable management
|
|
237
|
-
await withSpinner('Installing @nestjs/config...', '@nestjs/config installed', 'Failed to install @nestjs/config', async () => {
|
|
238
|
-
const success = await installDependency('@nestjs/config', projectRoot);
|
|
239
|
-
if (!success) {
|
|
240
|
-
throw new Error('Failed to install @nestjs/config');
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
// Copy application template additions
|
|
244
|
-
logger.info('Applying application customizations...');
|
|
245
|
-
const templatesDir = getCliTemplatesDir();
|
|
246
|
-
const applicationAdditionsDir = path.join(templatesDir, 'application-additions');
|
|
247
|
-
const applicationDir = path.join(projectRoot, 'apps', 'application');
|
|
248
|
-
copyTemplateFiles(applicationAdditionsDir, applicationDir);
|
|
249
|
-
renameEnvExample(applicationDir);
|
|
250
|
-
logger.success('Application customizations applied');
|
|
251
|
-
// Update config
|
|
252
|
-
updateConfig({
|
|
253
|
-
hasApplication: true,
|
|
254
|
-
applicationPath: 'apps/application',
|
|
88
|
+
/** Build the `init [name]` command. */
|
|
89
|
+
export function createInitCommand() {
|
|
90
|
+
return new Command('init')
|
|
91
|
+
.description('Scaffold a ForgeCart storefront in the target directory')
|
|
92
|
+
.argument('[name]', 'Target directory name (defaults to the current directory)')
|
|
93
|
+
.option('-t, --token <token>', 'ForgeCart channel token (required)')
|
|
94
|
+
.option('--api-url <url>', 'Shop API base URL written to the storefront environment', DEFAULT_SHOP_API_URL)
|
|
95
|
+
.option('-a, --application', 'Also scaffold a NestJS application (TODO: next phase)')
|
|
96
|
+
.action(async (name, options) => {
|
|
97
|
+
await runInit(name, options);
|
|
255
98
|
});
|
|
256
|
-
logger.success('Configuration updated');
|
|
257
|
-
logger.newline();
|
|
258
|
-
logger.box(`NestJS application added successfully!
|
|
259
|
-
|
|
260
|
-
Your application is available at:
|
|
261
|
-
apps/application/
|
|
262
|
-
|
|
263
|
-
To deploy:
|
|
264
|
-
cd apps/application
|
|
265
|
-
forgecart deploy`);
|
|
266
99
|
}
|
|
267
100
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/** `init:application` — add a NestJS application to an existing project. */
|
|
3
|
+
export declare function createInitApplicationCommand(): Command;
|
|
4
|
+
/** `deploy` — deploy the current project. */
|
|
5
|
+
export declare function createDeployCommand(): Command;
|
|
6
|
+
/** `list` — list deployments for the channel. */
|
|
7
|
+
export declare function createListCommand(): Command;
|
|
8
|
+
/** `status [type]` — show deployment status. */
|
|
9
|
+
export declare function createStatusCommand(): Command;
|
|
10
|
+
/** `logs [type]` — view deployment logs. */
|
|
11
|
+
export declare function createLogsCommand(): Command;
|
|
12
|
+
/** `delete <type>` — delete a deployment. */
|
|
13
|
+
export declare function createDeleteCommand(): Command;
|
|
14
|
+
/** `scale <type> <instances>` — scale a deployment. */
|
|
15
|
+
export declare function createScaleCommand(): Command;
|
|
16
|
+
/** `env` — manage environment variables (get/set/unset). */
|
|
17
|
+
export declare function createEnvCommand(): Command;
|
|
18
|
+
/** `whoami` — show current channel information. */
|
|
19
|
+
export declare function createWhoamiCommand(): Command;
|