quik-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 (97) hide show
  1. package/README.md +0 -0
  2. package/bin/quik.dev.ts +8 -0
  3. package/bin/quik.js +9 -0
  4. package/dist/commands/VersionCommand.d.ts +12 -0
  5. package/dist/commands/VersionCommand.d.ts.map +1 -0
  6. package/dist/commands/VersionCommand.js +13 -0
  7. package/dist/commands/VersionCommand.js.map +1 -0
  8. package/dist/commands/init/InitCommand.d.ts +21 -0
  9. package/dist/commands/init/InitCommand.d.ts.map +1 -0
  10. package/dist/commands/init/InitCommand.js +22 -0
  11. package/dist/commands/init/InitCommand.js.map +1 -0
  12. package/dist/commands/init/impl/astro.scaffold.d.ts +9 -0
  13. package/dist/commands/init/impl/astro.scaffold.d.ts.map +1 -0
  14. package/dist/commands/init/impl/astro.scaffold.js +23 -0
  15. package/dist/commands/init/impl/astro.scaffold.js.map +1 -0
  16. package/dist/commands/init/impl/init.impl.d.ts +3 -0
  17. package/dist/commands/init/impl/init.impl.d.ts.map +1 -0
  18. package/dist/commands/init/impl/init.impl.js +201 -0
  19. package/dist/commands/init/impl/init.impl.js.map +1 -0
  20. package/dist/commands/init/impl/nextjs.scaffold.d.ts +9 -0
  21. package/dist/commands/init/impl/nextjs.scaffold.d.ts.map +1 -0
  22. package/dist/commands/init/impl/nextjs.scaffold.js +29 -0
  23. package/dist/commands/init/impl/nextjs.scaffold.js.map +1 -0
  24. package/dist/commands/init/templates/astro/.env.template +23 -0
  25. package/dist/commands/init/templates/astro/api-proxy.template +8 -0
  26. package/dist/commands/init/templates/astro/env.template +23 -0
  27. package/dist/commands/init/templates/astro/page.template +14 -0
  28. package/dist/commands/init/templates/nextjs/api-proxy.template +25 -0
  29. package/dist/commands/init/templates/nextjs/config.template +15 -0
  30. package/dist/commands/init/templates/nextjs/env.template +23 -0
  31. package/dist/commands/init/templates/nextjs/layout.template +67 -0
  32. package/dist/commands/init/templates/nextjs/page.template +12 -0
  33. package/dist/commands/run/RunCommand.d.ts +13 -0
  34. package/dist/commands/run/RunCommand.d.ts.map +1 -0
  35. package/dist/commands/run/RunCommand.js +15 -0
  36. package/dist/commands/run/RunCommand.js.map +1 -0
  37. package/dist/commands/run/impl/run.impl.d.ts +3 -0
  38. package/dist/commands/run/impl/run.impl.d.ts.map +1 -0
  39. package/dist/commands/run/impl/run.impl.js +73 -0
  40. package/dist/commands/run/impl/run.impl.js.map +1 -0
  41. package/dist/core/Banner.d.ts +2 -0
  42. package/dist/core/Banner.d.ts.map +1 -0
  43. package/dist/core/Banner.js +11 -0
  44. package/dist/core/Banner.js.map +1 -0
  45. package/dist/core/BaseCommand.d.ts +6 -0
  46. package/dist/core/BaseCommand.d.ts.map +1 -0
  47. package/dist/core/BaseCommand.js +3 -0
  48. package/dist/core/BaseCommand.js.map +1 -0
  49. package/dist/core/CLI.d.ts +23 -0
  50. package/dist/core/CLI.d.ts.map +1 -0
  51. package/dist/core/CLI.js +119 -0
  52. package/dist/core/CLI.js.map +1 -0
  53. package/dist/core/CommandRegistry.d.ts +13 -0
  54. package/dist/core/CommandRegistry.d.ts.map +1 -0
  55. package/dist/core/CommandRegistry.js +42 -0
  56. package/dist/core/CommandRegistry.js.map +1 -0
  57. package/dist/core/ConfigLoader.d.ts +5 -0
  58. package/dist/core/ConfigLoader.d.ts.map +1 -0
  59. package/dist/core/ConfigLoader.js +14 -0
  60. package/dist/core/ConfigLoader.js.map +1 -0
  61. package/dist/core/EventBus.d.ts +9 -0
  62. package/dist/core/EventBus.d.ts.map +1 -0
  63. package/dist/core/EventBus.js +33 -0
  64. package/dist/core/EventBus.js.map +1 -0
  65. package/dist/core/Loader.d.ts +36 -0
  66. package/dist/core/Loader.d.ts.map +1 -0
  67. package/dist/core/Loader.js +127 -0
  68. package/dist/core/Loader.js.map +1 -0
  69. package/dist/core/Logger.d.ts +18 -0
  70. package/dist/core/Logger.d.ts.map +1 -0
  71. package/dist/core/Logger.js +67 -0
  72. package/dist/core/Logger.js.map +1 -0
  73. package/dist/core/PluginManager.d.ts +13 -0
  74. package/dist/core/PluginManager.d.ts.map +1 -0
  75. package/dist/core/PluginManager.js +47 -0
  76. package/dist/core/PluginManager.js.map +1 -0
  77. package/dist/core/QuikError.d.ts +52 -0
  78. package/dist/core/QuikError.d.ts.map +1 -0
  79. package/dist/core/QuikError.js +75 -0
  80. package/dist/core/QuikError.js.map +1 -0
  81. package/dist/core/TemplateRenderer.d.ts +27 -0
  82. package/dist/core/TemplateRenderer.d.ts.map +1 -0
  83. package/dist/core/TemplateRenderer.js +38 -0
  84. package/dist/core/TemplateRenderer.js.map +1 -0
  85. package/dist/index.d.ts +12 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +13 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/types/index.d.ts +55 -0
  90. package/dist/types/index.d.ts.map +1 -0
  91. package/dist/types/index.js +7 -0
  92. package/dist/types/index.js.map +1 -0
  93. package/dist/utils/PackageInstaller.d.ts +17 -0
  94. package/dist/utils/PackageInstaller.d.ts.map +1 -0
  95. package/dist/utils/PackageInstaller.js +100 -0
  96. package/dist/utils/PackageInstaller.js.map +1 -0
  97. package/package.json +46 -0
package/README.md ADDED
Binary file
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { CLI } from "../src/index.js";
4
+
5
+ const cli = new CLI();
6
+ cli.run(process.argv).catch(() => {
7
+ // Error already logged by CLI handler — exit silently
8
+ });
package/bin/quik.js ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { CLI } from "../dist/index.js";
4
+
5
+ const cli = new CLI();
6
+ cli.run(process.argv).catch((err) => {
7
+ console.error("Fatal error:", err);
8
+ process.exit(1);
9
+ });
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from "../core/BaseCommand.js";
2
+ import type { CommandContext } from "../types/index.js";
3
+ export declare class VersionCommand extends BaseCommand {
4
+ readonly meta: {
5
+ name: string;
6
+ description: string;
7
+ aliases: string[];
8
+ category: string;
9
+ };
10
+ execute(context: CommandContext): void;
11
+ }
12
+ //# sourceMappingURL=VersionCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionCommand.d.ts","sourceRoot":"","sources":["../../src/commands/VersionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,qBAAa,cAAe,SAAQ,WAAW;IAC7C,QAAQ,CAAC,IAAI;;;;;MAKX;IAEF,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAGvC"}
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from "../core/BaseCommand.js";
2
+ export class VersionCommand extends BaseCommand {
3
+ meta = {
4
+ name: "version",
5
+ description: "Show version information",
6
+ aliases: ["v", "--version"],
7
+ category: "general",
8
+ };
9
+ execute(context) {
10
+ context.logger.info("quik-cli v1.0.0");
11
+ }
12
+ }
13
+ //# sourceMappingURL=VersionCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionCommand.js","sourceRoot":"","sources":["../../src/commands/VersionCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,MAAM,OAAO,cAAe,SAAQ,WAAW;IACpC,IAAI,GAAG;QACd,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,0BAA0B;QACvC,OAAO,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC;QAC3B,QAAQ,EAAE,SAAS;KACpB,CAAC;IAEF,OAAO,CAAC,OAAuB;QAC7B,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACzC,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from "../../core/BaseCommand.js";
2
+ import type { CommandContext } from "../../types/index.js";
3
+ /**
4
+ * `quik init` — interactively scaffolds a new quik project.
5
+ * Asks for project name, API key, and framework, then creates folder structure.
6
+ */
7
+ export declare class InitCommand extends BaseCommand {
8
+ readonly meta: {
9
+ name: string;
10
+ description: string;
11
+ args: string;
12
+ aliases: string[];
13
+ category: string;
14
+ options: {
15
+ flag: string;
16
+ description: string;
17
+ }[];
18
+ };
19
+ execute(context: CommandContext): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=InitCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InitCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/init/InitCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;GAGG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C,QAAQ,CAAC,IAAI;;;;;;;;;;MASX;IAEI,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAItD"}
@@ -0,0 +1,22 @@
1
+ import { BaseCommand } from "../../core/BaseCommand.js";
2
+ /**
3
+ * `quik init` — interactively scaffolds a new quik project.
4
+ * Asks for project name, API key, and framework, then creates folder structure.
5
+ */
6
+ export class InitCommand extends BaseCommand {
7
+ meta = {
8
+ name: "init",
9
+ description: "interactively scaffold a new quik project",
10
+ args: "[project-name]",
11
+ aliases: ["i"],
12
+ category: "setup",
13
+ options: [
14
+ { flag: "-y, --yes", description: "accept defaults without prompting" },
15
+ ],
16
+ };
17
+ async execute(context) {
18
+ const { executeInit } = await import("./impl/init.impl.js");
19
+ await executeInit(context);
20
+ }
21
+ }
22
+ //# sourceMappingURL=InitCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InitCommand.js","sourceRoot":"","sources":["../../../src/commands/init/InitCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,WAAW;IACjC,IAAI,GAAG;QACd,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,2CAA2C;QACxD,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,CAAC,GAAG,CAAC;QACd,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,mCAAmC,EAAE;SACxE;KACF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,OAAuB;QACnC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC5D,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ interface EnvVars {
2
+ secretKey: string;
3
+ tenantSlug: string;
4
+ tenantApiKey: string;
5
+ apiBaseUrl: string;
6
+ }
7
+ export declare function scaffoldAstro(projectPath: string, env: EnvVars): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=astro.scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astro.scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/impl/astro.scaffold.ts"],"names":[],"mappings":"AASA,UAAU,OAAO;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -0,0 +1,23 @@
1
+ import { join, dirname } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { mkdir } from "node:fs/promises";
4
+ import { renderToFile } from "../../../core/TemplateRenderer.js";
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const TEMPLATES_DIR = join(__dirname, "../templates");
8
+ export async function scaffoldAstro(projectPath, env) {
9
+ // Create .env from template
10
+ await renderToFile(join(TEMPLATES_DIR, "astro/env.template"), join(projectPath, ".env"), {
11
+ TENANT_SLUG: env.tenantSlug,
12
+ TENANT_API_KEY: env.tenantApiKey,
13
+ API_BASE_URL: env.apiBaseUrl,
14
+ SECRET_KEY: env.secretKey,
15
+ });
16
+ // Create src/pages/[...slug].astro
17
+ await mkdir(join(projectPath, "src/pages"), { recursive: true });
18
+ await renderToFile(join(TEMPLATES_DIR, "astro/page.template"), join(projectPath, "src/pages/[...slug].astro"), {});
19
+ // Create src/pages/api/[...path].ts
20
+ await mkdir(join(projectPath, "src/pages/api"), { recursive: true });
21
+ await renderToFile(join(TEMPLATES_DIR, "astro/api-proxy.template"), join(projectPath, "src/pages/api/[...path].ts"), {});
22
+ }
23
+ //# sourceMappingURL=astro.scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astro.scaffold.js","sourceRoot":"","sources":["../../../../src/commands/init/impl/astro.scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAStD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,GAAY;IAEZ,4BAA4B;IAC5B,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,EACzC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB;QACE,WAAW,EAAE,GAAG,CAAC,UAAU;QAC3B,cAAc,EAAE,GAAG,CAAC,YAAY;QAChC,YAAY,EAAE,GAAG,CAAC,UAAU;QAC5B,UAAU,EAAE,GAAG,CAAC,SAAS;KAC1B,CACF,CAAC;IAEF,mCAAmC;IACnC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjE,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,qBAAqB,CAAC,EAC1C,IAAI,CAAC,WAAW,EAAE,2BAA2B,CAAC,EAC9C,EAAE,CACH,CAAC;IAEF,oCAAoC;IACpC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAErE,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,0BAA0B,CAAC,EAC/C,IAAI,CAAC,WAAW,EAAE,4BAA4B,CAAC,EAC/C,EAAE,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CommandContext } from "../../../types/index.js";
2
+ export declare function executeInit(context: CommandContext): Promise<void>;
3
+ //# sourceMappingURL=init.impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.impl.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/impl/init.impl.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAyE9D,wBAAsB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAkLxE"}
@@ -0,0 +1,201 @@
1
+ import enquirer from "enquirer";
2
+ import { spawn } from "node:child_process";
3
+ import { writeFile, mkdir, rm, readFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { randomBytes } from "node:crypto";
6
+ import { QuikError, ErrorCode } from "../../../core/QuikError.js";
7
+ import { loader } from "../../../core/Loader.js";
8
+ import { installGitHubPackage } from "../../../utils/PackageInstaller.js";
9
+ import { scaffoldNextjs } from "./nextjs.scaffold.js";
10
+ import { scaffoldAstro } from "./astro.scaffold.js";
11
+ const { prompt } = enquirer;
12
+ const GITHUB_PACKAGE = `@quikcr/quik-engine`;
13
+ /**
14
+ * Generates a secret key for AES-256 encryption.
15
+ */
16
+ function generateSecretKey() {
17
+ return randomBytes(32).toString("base64");
18
+ }
19
+ /**
20
+ * Fetches a GitHub token from an external API using the user's API key.
21
+ */
22
+ async function fetchGitHubToken(apiKey) {
23
+ let response;
24
+ try {
25
+ response = await fetch("http://localhost:3000/github-token", {
26
+ method: "POST",
27
+ headers: { "Content-Type": "application/json" },
28
+ body: JSON.stringify({ apiKey }),
29
+ });
30
+ }
31
+ catch (err) {
32
+ throw new QuikError(ErrorCode.NET_001, "network", `Network error: Unable to reach token API`, { cause: err instanceof Error ? err.message : String(err) });
33
+ }
34
+ if (!response.ok) {
35
+ throw new QuikError(ErrorCode.NET_001, "network", `Failed to fetch GitHub token: ${response.statusText}`, { details: { status: response.status, apiKeyPrefix: apiKey.slice(0, 8) + "..." } });
36
+ }
37
+ const data = (await response.json());
38
+ return data.token;
39
+ }
40
+ function runNpmInstall(cwd) {
41
+ return new Promise((resolve, reject) => {
42
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
43
+ const child = spawn(npmCmd, ["install"], {
44
+ cwd,
45
+ stdio: "inherit",
46
+ shell: process.platform === "win32",
47
+ windowsHide: true,
48
+ });
49
+ child.on("error", (err) => reject(err));
50
+ child.on("close", (code) => {
51
+ if (code === 0)
52
+ resolve();
53
+ else
54
+ reject(new Error(`npm install exited with code ${code}`));
55
+ });
56
+ });
57
+ }
58
+ export async function executeInit(context) {
59
+ const useDefaults = Boolean(context.options.yes);
60
+ const projectNameArg = context.args[0];
61
+ // Determine if in-place mode (no project name given)
62
+ const inPlace = !projectNameArg;
63
+ // In-place mode requires cwd to already be a project with package.json
64
+ if (inPlace) {
65
+ try {
66
+ await readFile(join(context.cwd, "package.json"), "utf-8");
67
+ }
68
+ catch {
69
+ throw new QuikError(ErrorCode.INIT_001, "init", "No package.json found. Run 'quik init <project-name>' to create a new project.");
70
+ }
71
+ }
72
+ const answers = useDefaults
73
+ ? {
74
+ projectName: projectNameArg ?? "my-quik-app",
75
+ tenantSlug: "",
76
+ tenantApiKey: "",
77
+ apiBaseUrl: "",
78
+ framework: "nextjs",
79
+ }
80
+ : await prompt([
81
+ ...(inPlace
82
+ ? []
83
+ : [
84
+ {
85
+ type: "input",
86
+ name: "projectName",
87
+ message: "What is your project name?",
88
+ initial: projectNameArg ?? "my-quik-app",
89
+ },
90
+ ]),
91
+ {
92
+ type: "input",
93
+ name: "tenantSlug",
94
+ message: "Enter your tenant slug:",
95
+ },
96
+ {
97
+ type: "input",
98
+ name: "tenantApiKey",
99
+ message: "Enter your tenant API key:",
100
+ },
101
+ {
102
+ type: "input",
103
+ name: "apiBaseUrl",
104
+ message: "Enter your API base URL:",
105
+ },
106
+ {
107
+ type: "select",
108
+ name: "framework",
109
+ message: "Which framework are you using?",
110
+ choices: ["nextjs", "astro", "remix", "none"],
111
+ initial: 0,
112
+ },
113
+ ]);
114
+ // Set projectName from answers or default for new project
115
+ const projectName = answers.projectName || "my-quik-app";
116
+ const projectPath = inPlace ? context.cwd : join(context.cwd, projectName);
117
+ // Create project folder only for new (non-in-place) projects
118
+ if (!inPlace) {
119
+ await mkdir(projectPath, { recursive: true });
120
+ }
121
+ const minDisplayMs = 1500;
122
+ const startTime = Date.now();
123
+ try {
124
+ loader.start("Creating project files", "creating");
125
+ const secretKey = generateSecretKey();
126
+ if (!inPlace) {
127
+ // Write package.json for new projects
128
+ const packageJson = {
129
+ name: projectName,
130
+ version: "0.1.0",
131
+ type: "module",
132
+ scripts: {
133
+ dev: "quik dev",
134
+ build: "quik build",
135
+ },
136
+ dependencies: {
137
+ [GITHUB_PACKAGE]: "^1.0.29",
138
+ },
139
+ };
140
+ await loader.stepFor("Configuring package.json", "creating");
141
+ await writeFile(join(projectPath, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
142
+ }
143
+ // Fetch GitHub token and install private package
144
+ await loader.stepFor("Authenticating with GitHub registry", "webrequest");
145
+ const githubToken = await fetchGitHubToken(answers.tenantApiKey);
146
+ await loader.stepFor("Installing quik-engine", "installing", 2000, () => installGitHubPackage("@quikcr/quik-engine", "1.0.29", githubToken, projectPath));
147
+ if (!inPlace) {
148
+ // Run npm install only for new projects (existing projects already have node_modules)
149
+ await loader.stepFor("Installing dependencies", "installing", 2000, () => runNpmInstall(projectPath));
150
+ }
151
+ // Framework-specific scaffolding
152
+ if (answers.framework === "nextjs") {
153
+ await loader.stepFor("Scaffolding Next.js files", "creating");
154
+ await scaffoldNextjs(projectPath, {
155
+ secretKey,
156
+ tenantSlug: answers.tenantSlug,
157
+ tenantApiKey: answers.tenantApiKey,
158
+ apiBaseUrl: answers.apiBaseUrl,
159
+ });
160
+ }
161
+ else if (answers.framework === "astro") {
162
+ await loader.stepFor("Scaffolding Astro files", "creating");
163
+ await scaffoldAstro(projectPath, {
164
+ secretKey,
165
+ tenantSlug: answers.tenantSlug,
166
+ tenantApiKey: answers.tenantApiKey,
167
+ apiBaseUrl: answers.apiBaseUrl,
168
+ });
169
+ }
170
+ // Ensure loader was visible for at least 1.5s
171
+ const elapsed = Date.now() - startTime;
172
+ if (elapsed < minDisplayMs) {
173
+ await new Promise((resolve) => setTimeout(resolve, minDisplayMs - elapsed));
174
+ }
175
+ if (inPlace) {
176
+ loader.done("Quik setup complete!");
177
+ context.logger.success(".env configured");
178
+ context.logger.success("Quik engine installed");
179
+ context.logger.info(`Framework: ${answers.framework}`);
180
+ }
181
+ else {
182
+ loader.done(`Project ${projectName} initialized successfully!`);
183
+ context.logger.success(`Created ${projectName}/`);
184
+ context.logger.success(`Created ${projectName}/.env`);
185
+ context.logger.success(`Created ${projectName}/.npmrc`);
186
+ context.logger.success(`Created ${projectName}/package.json`);
187
+ context.logger.info(`Framework: ${answers.framework}`);
188
+ }
189
+ }
190
+ catch (error) {
191
+ if (!inPlace) {
192
+ // Rollback: remove project folder on failure (only for new projects)
193
+ await loader.stepFor("Cleaning up...", "deleting", 2000, async () => {
194
+ await rm(projectPath, { recursive: true, force: true });
195
+ });
196
+ }
197
+ loader.fail("Failed to initialize project");
198
+ throw error;
199
+ }
200
+ }
201
+ //# sourceMappingURL=init.impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.impl.js","sourceRoot":"","sources":["../../../../src/commands/init/impl/init.impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ interface EnvVars {
2
+ secretKey: string;
3
+ tenantSlug: string;
4
+ tenantApiKey: string;
5
+ apiBaseUrl: string;
6
+ }
7
+ export declare function scaffoldNextjs(projectPath: string, env: EnvVars): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=nextjs.scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/impl/nextjs.scaffold.ts"],"names":[],"mappings":"AASA,UAAU,OAAO;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
@@ -0,0 +1,29 @@
1
+ import { join, dirname } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { mkdir } from "node:fs/promises";
4
+ import { renderToFile } from "../../../core/TemplateRenderer.js";
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const TEMPLATES_DIR = join(__dirname, "../templates");
8
+ export async function scaffoldNextjs(projectPath, env) {
9
+ // Create .env from template
10
+ await renderToFile(join(TEMPLATES_DIR, "nextjs/env.template"), join(projectPath, ".env"), {
11
+ TENANT_SLUG: env.tenantSlug,
12
+ TENANT_API_KEY: env.tenantApiKey,
13
+ API_BASE_URL: env.apiBaseUrl,
14
+ SECRET_KEY: env.secretKey,
15
+ });
16
+ // Create src/layout.tsx
17
+ await renderToFile(join(TEMPLATES_DIR, "nextjs/layout.template"), join(projectPath, "src/app/layout.tsx"), {});
18
+ // Create src/app/[...slug] directory
19
+ await mkdir(join(projectPath, "src/app/[...slug]"), { recursive: true });
20
+ // Create the catch-all page
21
+ await renderToFile(join(TEMPLATES_DIR, "nextjs/page.template"), join(projectPath, "src/app/[...slug]/page.tsx"), {});
22
+ // Create src/app/api/[...path] directory
23
+ await mkdir(join(projectPath, "src/app/api/[...path]"), { recursive: true });
24
+ // Create the API proxy route
25
+ await renderToFile(join(TEMPLATES_DIR, "nextjs/api-proxy.template"), join(projectPath, "src/app/api/[...path]/route.ts"), {});
26
+ // Create nextjs config
27
+ await renderToFile(join(TEMPLATES_DIR, "nextjs/config.template"), join(projectPath, "next.config.ts"), {});
28
+ }
29
+ //# sourceMappingURL=nextjs.scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.scaffold.js","sourceRoot":"","sources":["../../../../src/commands/init/impl/nextjs.scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAStD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAmB,EACnB,GAAY;IAEZ,4BAA4B;IAC5B,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,qBAAqB,CAAC,EAC1C,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB;QACE,WAAW,EAAE,GAAG,CAAC,UAAU;QAC3B,cAAc,EAAE,GAAG,CAAC,YAAY;QAChC,YAAY,EAAE,GAAG,CAAC,UAAU;QAC5B,UAAU,EAAE,GAAG,CAAC,SAAS;KAC1B,CACF,CAAC;IAEF,wBAAwB;IACxB,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,wBAAwB,CAAC,EAC7C,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,EACvC,EAAE,CACH,CAAC;IAEF,qCAAqC;IACrC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzE,4BAA4B;IAC5B,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,EAC3C,IAAI,CAAC,WAAW,EAAE,4BAA4B,CAAC,EAC/C,EAAE,CACH,CAAC;IAEF,yCAAyC;IACzC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7E,6BAA6B;IAC7B,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,2BAA2B,CAAC,EAChD,IAAI,CAAC,WAAW,EAAE,gCAAgC,CAAC,EACnD,EAAE,CACH,CAAC;IAEA,uBAAuB;IACzB,MAAM,YAAY,CAChB,IAAI,CAAC,aAAa,EAAE,wBAAwB,CAAC,EAC7C,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EACnC,EAAE,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ # Host runtime configuration.
2
+ # Variables prefixed with NEXT_PUBLIC_ are exposed to the browser by Next.js;
3
+ # the package's `<QuikConfigProvider>` reads them on the client.
4
+ # Variables without the prefix are server-only — the proxy route reads
5
+ # `PROXY_ENCRYPTION_KEY` from this file.
6
+
7
+ # Tenant identity forwarded to the package's transport layer.
8
+ NEXT_PUBLIC_TENANT_SLUG={{TENANT_SLUG}}
9
+ NEXT_PUBLIC_TENANT_API_KEY={{TENANT_API_KEY}}
10
+
11
+ # Where the package's `apiFetch` sends requests. The host decides where
12
+ # to mount the package's API proxy (or whether to point at the backend
13
+ # directly). This value flows through `<QuikConfigProvider apiBaseUrl=...>`
14
+ # into `apiFetch`. The package's internal `QUIK_API_BASE_URL` constant
15
+ # (in `src/lib/transport/api-config.ts`) acts as a fallback if this is
16
+ # unset.
17
+ NEXT_PUBLIC_API_BASE_URL={{API_BASE_URL}}
18
+
19
+ # E2E encryption (AES-256-GCM). Both keys must hold the same 32-byte
20
+ # base64-encoded secret for the round-trip to work. With either key
21
+ # absent, requests pass through as plain JSON.
22
+ PROXY_ENCRYPTION_KEY={{SECRET_KEY}}
23
+ NEXT_PUBLIC_ENCRYPTION_KEY={{SECRET_KEY}}
@@ -0,0 +1,8 @@
1
+ import type { APIRoute } from 'astro';
2
+ import { createProxyHandler } from '@qwik/shared';
3
+
4
+ // BE server URL - server-side only, never reaches the browser
5
+ const BE_URL = import.meta.env.APP_BASE_URL || 'http://localhost:3001';
6
+ const ENCRYPTION_KEY = import.meta.env.PROXY_ENCRYPTION_KEY;
7
+
8
+ export const ALL: APIRoute = (ctx) => createProxyHandler({ baseUrl: BE_URL, encryptionKey: ENCRYPTION_KEY })(ctx.request, { path: ctx.params.path as string | string[] });
@@ -0,0 +1,23 @@
1
+ # Host runtime configuration.
2
+ # Variables prefixed with NEXT_PUBLIC_ are exposed to the browser by Next.js;
3
+ # the package's `<QuikConfigProvider>` reads them on the client.
4
+ # Variables without the prefix are server-only — the proxy route reads
5
+ # `PROXY_ENCRYPTION_KEY` from this file.
6
+
7
+ # Tenant identity forwarded to the package's transport layer.
8
+ NEXT_PUBLIC_TENANT_SLUG={{TENANT_SLUG}}
9
+ NEXT_PUBLIC_TENANT_API_KEY={{TENANT_API_KEY}}
10
+
11
+ # Where the package's `apiFetch` sends requests. The host decides where
12
+ # to mount the package's API proxy (or whether to point at the backend
13
+ # directly). This value flows through `<QuikConfigProvider apiBaseUrl=...>`
14
+ # into `apiFetch`. The package's internal `QUIK_API_BASE_URL` constant
15
+ # (in `src/lib/transport/api-config.ts`) acts as a fallback if this is
16
+ # unset.
17
+ NEXT_PUBLIC_API_BASE_URL={{API_BASE_URL}}
18
+
19
+ # E2E encryption (AES-256-GCM). Both keys must hold the same 32-byte
20
+ # base64-encoded secret for the round-trip to work. With either key
21
+ # absent, requests pass through as plain JSON.
22
+ PROXY_ENCRYPTION_KEY={{SECRET_KEY}}
23
+ NEXT_PUBLIC_ENCRYPTION_KEY={{SECRET_KEY}}
@@ -0,0 +1,14 @@
1
+ ---
2
+ import Layout from '../../layouts/Layout.astro';
3
+ import QwikEngine from '@qwik/engine';
4
+
5
+ const { slug } = Astro.params;
6
+ const currentPath = `/admin/${slug || ''}`;
7
+ // Astro [...slug] gives us "erm/financial" as a string, split to get array
8
+ const slugArray = slug ? slug.split('/') : [];
9
+ const params = { slug: slugArray };
10
+ ---
11
+
12
+ <Layout>
13
+ <QwikEngine params={params} currentPath={currentPath} client:load />
14
+ </Layout>
@@ -0,0 +1,25 @@
1
+ import { createProxyHandler } from "@quikcr/quik-engine";
2
+ import type { NextRequest } from "next/server";
3
+
4
+ // The proxy's upstream backend URL is owned by the package —
5
+ // `createProxyHandler` reads it from the internal QUIK_BACKEND_API_URL
6
+ // constant. Hosts do not need to configure or pass it.
7
+ const ENCRYPTION_KEY = process.env.PROXY_ENCRYPTION_KEY;
8
+
9
+ const proxy = createProxyHandler({
10
+ encryptionKey: ENCRYPTION_KEY,
11
+ });
12
+
13
+ const handler = async (
14
+ req: NextRequest,
15
+ { params }: { params: Promise<{ path: string[] }> },
16
+ ) => {
17
+ const { path } = await params;
18
+ return proxy(req, { path });
19
+ };
20
+
21
+ export const GET = handler;
22
+ export const POST = handler;
23
+ export const PUT = handler;
24
+ export const PATCH = handler;
25
+ export const DELETE = handler;
@@ -0,0 +1,15 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* config options here */ images: {
5
+ remotePatterns: [
6
+ {
7
+ protocol: "https",
8
+ hostname: "images.unsplash.com",
9
+ pathname: "/**",
10
+ },
11
+ ],
12
+ },
13
+ };
14
+
15
+ export default nextConfig;
@@ -0,0 +1,23 @@
1
+ # Host runtime configuration.
2
+ # Variables prefixed with NEXT_PUBLIC_ are exposed to the browser by Next.js;
3
+ # the package's `<QuikConfigProvider>` reads them on the client.
4
+ # Variables without the prefix are server-only — the proxy route reads
5
+ # `PROXY_ENCRYPTION_KEY` from this file.
6
+
7
+ # Tenant identity forwarded to the package's transport layer.
8
+ NEXT_PUBLIC_TENANT_SLUG={{TENANT_SLUG}}
9
+ NEXT_PUBLIC_TENANT_API_KEY={{TENANT_API_KEY}}
10
+
11
+ # Where the package's `apiFetch` sends requests. The host decides where
12
+ # to mount the package's API proxy (or whether to point at the backend
13
+ # directly). This value flows through `<QuikConfigProvider apiBaseUrl=...>`
14
+ # into `apiFetch`. The package's internal `QUIK_API_BASE_URL` constant
15
+ # (in `src/lib/transport/api-config.ts`) acts as a fallback if this is
16
+ # unset.
17
+ NEXT_PUBLIC_API_BASE_URL={{API_BASE_URL}}
18
+
19
+ # E2E encryption (AES-256-GCM). Both keys must hold the same 32-byte
20
+ # base64-encoded secret for the round-trip to work. With either key
21
+ # absent, requests pass through as plain JSON.
22
+ PROXY_ENCRYPTION_KEY={{SECRET_KEY}}
23
+ NEXT_PUBLIC_ENCRYPTION_KEY={{SECRET_KEY}}
@@ -0,0 +1,67 @@
1
+ import { QuikConfigProvider, QuikThemeConfig } from "@quikcr/quik-engine";
2
+ import type { Metadata } from "next";
3
+ import { Poppins } from "next/font/google";
4
+ import type * as React from "react";
5
+ import "@quikcr/quik-engine/styles.css";
6
+ // import "./globals.css";
7
+
8
+ const poppins = Poppins({
9
+ variable: "--font-poppins",
10
+ subsets: ["latin"],
11
+ display: "swap",
12
+ weight: ["400", "500", "600", "700"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "QuikEngine — The operating system for SaaS products",
17
+ description:
18
+ "QuikEngine is a self-contained Next.js 16+ package that powers CRM, HRMS, Accounting, ERP, and more — built as the foundation for your next SaaS product.",
19
+ };
20
+
21
+ /**
22
+ * The host application's root layout.
23
+ *
24
+ * Owns the <html>/<body> shell. The package's compiled stylesheet is
25
+ * imported via @import inside `app/globals.css` (first line) so the
26
+ * host's :root / .dark overrides win on cascade.
27
+ *
28
+ * `<QuikConfigProvider>` is the package's opt-in channel for host
29
+ * configuration. The demo forwards NEXT_PUBLIC_API_URL and
30
+ * NEXT_PUBLIC_API_KEY so any future console screen that calls the host
31
+ * API can read them through `useQuikConfig()`.
32
+ *
33
+ * `suppressHydrationWarning` silences the expected `next-themes` warning
34
+ * when the package flips the `dark` class on <html> after mount.
35
+ */
36
+
37
+ const theme: QuikThemeConfig = {
38
+ primaryColor: "#50C878",
39
+ fontFamily: "geist-sans",
40
+ fontSize: 0.9,
41
+ borderRadius: 0.75,
42
+ };
43
+
44
+ export default function RootLayout({
45
+ children,
46
+ }: {
47
+ children: React.ReactNode;
48
+ }) {
49
+ return (
50
+ <html
51
+ lang="en"
52
+ className={`${poppins.variable} h-full antialiased`}
53
+ suppressHydrationWarning
54
+ >
55
+ <body className="min-h-full bg-background font-sans text-foreground">
56
+ <QuikConfigProvider
57
+ tenantSlug={process.env.NEXT_PUBLIC_TENANT_SLUG ?? ""}
58
+ tenantApiKey={process.env.NEXT_PUBLIC_TENANT_API_KEY ?? ""}
59
+ apiBaseUrl={process.env.NEXT_PUBLIC_API_BASE_URL ?? ""}
60
+ theme={theme}
61
+ >
62
+ {children}
63
+ </QuikConfigProvider>
64
+ </body>
65
+ </html>
66
+ );
67
+ }