@axiomify/cli 3.1.0 → 4.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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.d.ts CHANGED
@@ -1,2 +1 @@
1
1
  #!/usr/bin/env node
2
- export {};
package/dist/index.js CHANGED
@@ -1,34 +1,284 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const commander_1 = require("commander");
5
- const build_1 = require("./commands/build");
6
- const dev_1 = require("./commands/dev");
7
- const init_1 = require("./commands/init");
8
- const routes_1 = require("./commands/routes");
9
- const program = new commander_1.Command();
10
- program
11
- .name('axiomify')
12
- .description('The official CLI for the Axiomify framework')
13
- .version('1.0.0');
14
- program
15
- .command('init')
16
- .description('Bootstrap a new Axiomify project')
17
- .argument('[directory]', 'Target directory', '.')
18
- .action(init_1.initProject);
19
- program
20
- .command('dev')
21
- .description('Start the development server with hot-reload')
22
- .argument('[entry]', 'Entry file', 'src/index.ts')
23
- .action(dev_1.devServer);
24
- program
25
- .command('build')
26
- .description('Compile the application for production')
27
- .argument('[entry]', 'Entry file', 'src/index.ts')
28
- .action(build_1.buildProject);
29
- program
30
- .command('routes')
31
- .description('Inspect and list all registered routes in the application')
32
- .argument('[entry]', 'Entry file', 'src/index.ts')
33
- .action(routes_1.inspectRoutes);
2
+ 'use strict';
3
+
4
+ var commander = require('commander');
5
+ var esbuild = require('esbuild');
6
+ var path4 = require('path');
7
+ var fs = require('fs');
8
+ var child_process = require('child_process');
9
+ var fs2 = require('fs/promises');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ function _interopNamespace(e) {
14
+ if (e && e.__esModule) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
32
+ var path4__default = /*#__PURE__*/_interopDefault(path4);
33
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
34
+ var fs2__default = /*#__PURE__*/_interopDefault(fs2);
35
+
36
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
37
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
38
+ }) : x)(function(x) {
39
+ if (typeof require !== "undefined") return require.apply(this, arguments);
40
+ throw Error('Dynamic require of "' + x + '" is not supported');
41
+ });
42
+ function getUserExternals(cwd) {
43
+ try {
44
+ const pkgPath = path4__default.default.join(cwd, "package.json");
45
+ if (fs__default.default.existsSync(pkgPath)) {
46
+ const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf8"));
47
+ const deps = Object.keys(pkg.dependencies || {});
48
+ const devDeps = Object.keys(pkg.devDependencies || {});
49
+ return [...deps, ...devDeps];
50
+ }
51
+ } catch (err) {
52
+ console.warn(
53
+ "[Axiomify CLI] Failed to read package.json, defaulting to empty externals."
54
+ );
55
+ }
56
+ return [];
57
+ }
58
+
59
+ // src/commands/build.ts
60
+ async function buildProject(entry) {
61
+ const entryPath = path4__default.default.resolve(process.cwd(), entry);
62
+ const outPath = path4__default.default.resolve(process.cwd(), "dist/index.js");
63
+ const userExternals = getUserExternals(process.cwd());
64
+ console.log(`\u{1F528} Building production bundle from ${entry}...`);
65
+ try {
66
+ await esbuild__namespace.build({
67
+ entryPoints: [entryPath],
68
+ bundle: true,
69
+ platform: "node",
70
+ target: "node18",
71
+ outfile: outPath,
72
+ minify: true,
73
+ keepNames: true,
74
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])]
75
+ });
76
+ console.log(`\u2705 Build successful: ${outPath}`);
77
+ } catch (error) {
78
+ console.error("\u274C Build failed:", error);
79
+ process.exit(1);
80
+ }
81
+ }
82
+ async function devServer(entry) {
83
+ const entryPath = path4__default.default.resolve(process.cwd(), entry);
84
+ const outPath = path4__default.default.resolve(process.cwd(), ".axiomify/dev.js");
85
+ let child = null;
86
+ const restartServer = () => {
87
+ if (child) {
88
+ child.removeAllListeners("exit");
89
+ child.once("exit", () => {
90
+ child = child_process.spawn("node", [outPath], { stdio: "inherit" });
91
+ });
92
+ child.kill("SIGKILL");
93
+ } else {
94
+ child = child_process.spawn("node", [outPath], { stdio: "inherit" });
95
+ }
96
+ };
97
+ const watchPlugin = {
98
+ name: "watch-plugin",
99
+ setup(build3) {
100
+ build3.onEnd((result) => {
101
+ if (result.errors.length > 0) {
102
+ console.error("\u274C Build failed. Waiting for changes...");
103
+ } else {
104
+ restartServer();
105
+ }
106
+ });
107
+ }
108
+ };
109
+ const userExternals = getUserExternals(process.cwd());
110
+ const ctx = await esbuild__namespace.context({
111
+ entryPoints: [entryPath],
112
+ bundle: true,
113
+ platform: "node",
114
+ outfile: outPath,
115
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])],
116
+ plugins: [watchPlugin]
117
+ });
118
+ let shuttingDown = false;
119
+ const shutdown = async (signal) => {
120
+ if (shuttingDown) return;
121
+ shuttingDown = true;
122
+ console.log(`
123
+ \u{1F44B} Received ${signal}, shutting down dev server...`);
124
+ if (child) {
125
+ child.removeAllListeners("exit");
126
+ child.kill("SIGTERM");
127
+ setTimeout(() => {
128
+ if (child && !child.killed) child.kill("SIGKILL");
129
+ }, 2e3).unref();
130
+ }
131
+ try {
132
+ await ctx.dispose();
133
+ } catch {
134
+ }
135
+ process.exit(0);
136
+ };
137
+ process.once("SIGINT", () => shutdown("SIGINT"));
138
+ process.once("SIGTERM", () => shutdown("SIGTERM"));
139
+ console.log(`\u{1F440} Axiomify Dev Engine watching for changes...`);
140
+ await ctx.watch();
141
+ }
142
+ async function initProject(targetDir, options = {}) {
143
+ const dir = path4__default.default.resolve(process.cwd(), targetDir);
144
+ await fs2__default.default.mkdir(path4__default.default.join(dir, "src"), { recursive: true });
145
+ const targets = [
146
+ path4__default.default.join(dir, "package.json"),
147
+ path4__default.default.join(dir, "tsconfig.json"),
148
+ path4__default.default.join(dir, "src", "index.ts")
149
+ ];
150
+ const collisions = targets.filter((p) => fs.existsSync(p));
151
+ if (collisions.length > 0 && !options.force) {
152
+ console.error(
153
+ "\u274C Refusing to overwrite existing files:\n" + collisions.map((p) => ` - ${p}`).join("\n") + "\n\nRe-run with '--force' if you really want to replace them."
154
+ );
155
+ process.exit(1);
156
+ }
157
+ const pkgJson = {
158
+ name: "axiomify-app",
159
+ version: "1.0.0",
160
+ private: true,
161
+ scripts: {
162
+ dev: "axiomify dev src/index.ts",
163
+ build: "axiomify build src/index.ts",
164
+ start: "node dist/index.js",
165
+ routes: "axiomify routes src/index.ts"
166
+ },
167
+ dependencies: {
168
+ "@axiomify/core": "latest",
169
+ "@axiomify/express": "latest"
170
+ },
171
+ devDependencies: {
172
+ // Keep scaffolded projects on the same TS major as the workspace
173
+ // (^6) so types like `satisfies`, `const` type parameters, etc., don't
174
+ // drift between the framework and user code.
175
+ typescript: "^6.0.0",
176
+ "@types/node": "^22.0.0"
177
+ }
178
+ };
179
+ const tsConfig = {
180
+ compilerOptions: {
181
+ target: "ES2022",
182
+ module: "CommonJS",
183
+ moduleResolution: "node",
184
+ strict: true,
185
+ esModuleInterop: true,
186
+ skipLibCheck: true,
187
+ forceConsistentCasingInFileNames: true,
188
+ outDir: "./dist"
189
+ },
190
+ include: ["src/**/*"]
191
+ };
192
+ const indexTs = `import { Axiomify, z } from '@axiomify/core';
193
+ import { ExpressAdapter } from '@axiomify/express';
194
+
195
+ // Exporting the app instance is required for the 'axiomify routes' CLI command
196
+ export const app = new Axiomify();
197
+
198
+ app.route({
199
+ method: 'GET',
200
+ path: '/health',
201
+ handler: async (req, res) => {
202
+ res.status(200).send({ status: 'healthy', timestamp: Date.now() }, 'System Operational');
203
+ }
204
+ });
205
+
206
+ // Prevent listening during CLI inspection
207
+ if (require.main === module) {
208
+ const adapter = new ExpressAdapter(app);
209
+ adapter.listen(3000, () => console.log('\u{1F680} Axiomify engine online on port 3000'));
210
+ }
211
+ `;
212
+ await fs2__default.default.writeFile(
213
+ path4__default.default.join(dir, "package.json"),
214
+ JSON.stringify(pkgJson, null, 2)
215
+ );
216
+ await fs2__default.default.writeFile(
217
+ path4__default.default.join(dir, "tsconfig.json"),
218
+ JSON.stringify(tsConfig, null, 2)
219
+ );
220
+ await fs2__default.default.writeFile(path4__default.default.join(dir, "src", "index.ts"), indexTs);
221
+ console.log(`\u2705 Axiomify project initialized in ${dir}`);
222
+ console.log(`\u{1F4E6} Run 'npm install' to install dependencies.`);
223
+ }
224
+ async function inspectRoutes(entry) {
225
+ const entryPath = path4__default.default.resolve(process.cwd(), entry);
226
+ const tempPath = path4__default.default.resolve(process.cwd(), ".axiomify/inspect.cjs");
227
+ const userExternals = getUserExternals(process.cwd());
228
+ try {
229
+ await esbuild__namespace.build({
230
+ entryPoints: [entryPath],
231
+ bundle: true,
232
+ platform: "node",
233
+ format: "cjs",
234
+ outfile: tempPath,
235
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])]
236
+ });
237
+ try {
238
+ delete __require.cache[__require.resolve(tempPath)];
239
+ } catch (e) {
240
+ }
241
+ const mod = __require(tempPath);
242
+ const app = mod.app || mod.default;
243
+ if (!app || typeof app.registeredRoutes === "undefined") {
244
+ console.error("\u274C Error: Could not find an exported Axiomify instance.");
245
+ console.error(
246
+ "Ensure your entry file exports the app: `export const app = new Axiomify();`"
247
+ );
248
+ process.exit(1);
249
+ }
250
+ console.log("\n\u{1F9ED} Registered Axiomify Routes:");
251
+ console.log("----------------------------------------------------");
252
+ console.log(`${"METHOD".padEnd(10)} | ${"PATH".padEnd(30)} | VALIDATION`);
253
+ console.log("----------------------------------------------------");
254
+ app.registeredRoutes.forEach((route) => {
255
+ const schemas = [];
256
+ if (route.schema?.body) schemas.push("Body");
257
+ if (route.schema?.query) schemas.push("Query");
258
+ if (route.schema?.params) schemas.push("Params");
259
+ if (route.schema?.response) schemas.push("Response");
260
+ if (route.schema?.files) schemas.push("Files");
261
+ const validationStr = schemas.length > 0 ? schemas.join(", ") : "None";
262
+ console.log(
263
+ `${route.method.padEnd(10)} | ${route.path.padEnd(
264
+ 30
265
+ )} | ${validationStr}`
266
+ );
267
+ });
268
+ console.log("----------------------------------------------------\n");
269
+ } catch (error) {
270
+ console.error("\u274C Failed to inspect routes:", error);
271
+ } finally {
272
+ await fs2__default.default.rm(path4__default.default.dirname(tempPath), { recursive: true, force: true }).catch(() => {
273
+ });
274
+ }
275
+ }
276
+
277
+ // src/index.ts
278
+ var program = new commander.Command();
279
+ program.name("axiomify").description("The official CLI for the Axiomify framework").version("1.0.0");
280
+ program.command("init").description("Bootstrap a new Axiomify project").argument("[directory]", "Target directory", ".").option("-f, --force", "Overwrite existing project files", false).action((directory, options) => initProject(directory, options));
281
+ program.command("dev").description("Start the development server with hot-reload").argument("[entry]", "Entry file", "src/index.ts").action(devServer);
282
+ program.command("build").description("Compile the application for production").argument("[entry]", "Entry file", "src/index.ts").action(buildProject);
283
+ program.command("routes").description("Inspect and list all registered routes in the application").argument("[entry]", "Entry file", "src/index.ts").action(inspectRoutes);
34
284
  program.parse(process.argv);
package/dist/index.mjs ADDED
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import * as esbuild from 'esbuild';
4
+ import path4 from 'path';
5
+ import fs, { existsSync } from 'fs';
6
+ import { spawn } from 'child_process';
7
+ import fs2 from 'fs/promises';
8
+
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ function getUserExternals(cwd) {
16
+ try {
17
+ const pkgPath = path4.join(cwd, "package.json");
18
+ if (fs.existsSync(pkgPath)) {
19
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
20
+ const deps = Object.keys(pkg.dependencies || {});
21
+ const devDeps = Object.keys(pkg.devDependencies || {});
22
+ return [...deps, ...devDeps];
23
+ }
24
+ } catch (err) {
25
+ console.warn(
26
+ "[Axiomify CLI] Failed to read package.json, defaulting to empty externals."
27
+ );
28
+ }
29
+ return [];
30
+ }
31
+
32
+ // src/commands/build.ts
33
+ async function buildProject(entry) {
34
+ const entryPath = path4.resolve(process.cwd(), entry);
35
+ const outPath = path4.resolve(process.cwd(), "dist/index.js");
36
+ const userExternals = getUserExternals(process.cwd());
37
+ console.log(`\u{1F528} Building production bundle from ${entry}...`);
38
+ try {
39
+ await esbuild.build({
40
+ entryPoints: [entryPath],
41
+ bundle: true,
42
+ platform: "node",
43
+ target: "node18",
44
+ outfile: outPath,
45
+ minify: true,
46
+ keepNames: true,
47
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])]
48
+ });
49
+ console.log(`\u2705 Build successful: ${outPath}`);
50
+ } catch (error) {
51
+ console.error("\u274C Build failed:", error);
52
+ process.exit(1);
53
+ }
54
+ }
55
+ async function devServer(entry) {
56
+ const entryPath = path4.resolve(process.cwd(), entry);
57
+ const outPath = path4.resolve(process.cwd(), ".axiomify/dev.js");
58
+ let child = null;
59
+ const restartServer = () => {
60
+ if (child) {
61
+ child.removeAllListeners("exit");
62
+ child.once("exit", () => {
63
+ child = spawn("node", [outPath], { stdio: "inherit" });
64
+ });
65
+ child.kill("SIGKILL");
66
+ } else {
67
+ child = spawn("node", [outPath], { stdio: "inherit" });
68
+ }
69
+ };
70
+ const watchPlugin = {
71
+ name: "watch-plugin",
72
+ setup(build3) {
73
+ build3.onEnd((result) => {
74
+ if (result.errors.length > 0) {
75
+ console.error("\u274C Build failed. Waiting for changes...");
76
+ } else {
77
+ restartServer();
78
+ }
79
+ });
80
+ }
81
+ };
82
+ const userExternals = getUserExternals(process.cwd());
83
+ const ctx = await esbuild.context({
84
+ entryPoints: [entryPath],
85
+ bundle: true,
86
+ platform: "node",
87
+ outfile: outPath,
88
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])],
89
+ plugins: [watchPlugin]
90
+ });
91
+ let shuttingDown = false;
92
+ const shutdown = async (signal) => {
93
+ if (shuttingDown) return;
94
+ shuttingDown = true;
95
+ console.log(`
96
+ \u{1F44B} Received ${signal}, shutting down dev server...`);
97
+ if (child) {
98
+ child.removeAllListeners("exit");
99
+ child.kill("SIGTERM");
100
+ setTimeout(() => {
101
+ if (child && !child.killed) child.kill("SIGKILL");
102
+ }, 2e3).unref();
103
+ }
104
+ try {
105
+ await ctx.dispose();
106
+ } catch {
107
+ }
108
+ process.exit(0);
109
+ };
110
+ process.once("SIGINT", () => shutdown("SIGINT"));
111
+ process.once("SIGTERM", () => shutdown("SIGTERM"));
112
+ console.log(`\u{1F440} Axiomify Dev Engine watching for changes...`);
113
+ await ctx.watch();
114
+ }
115
+ async function initProject(targetDir, options = {}) {
116
+ const dir = path4.resolve(process.cwd(), targetDir);
117
+ await fs2.mkdir(path4.join(dir, "src"), { recursive: true });
118
+ const targets = [
119
+ path4.join(dir, "package.json"),
120
+ path4.join(dir, "tsconfig.json"),
121
+ path4.join(dir, "src", "index.ts")
122
+ ];
123
+ const collisions = targets.filter((p) => existsSync(p));
124
+ if (collisions.length > 0 && !options.force) {
125
+ console.error(
126
+ "\u274C Refusing to overwrite existing files:\n" + collisions.map((p) => ` - ${p}`).join("\n") + "\n\nRe-run with '--force' if you really want to replace them."
127
+ );
128
+ process.exit(1);
129
+ }
130
+ const pkgJson = {
131
+ name: "axiomify-app",
132
+ version: "1.0.0",
133
+ private: true,
134
+ scripts: {
135
+ dev: "axiomify dev src/index.ts",
136
+ build: "axiomify build src/index.ts",
137
+ start: "node dist/index.js",
138
+ routes: "axiomify routes src/index.ts"
139
+ },
140
+ dependencies: {
141
+ "@axiomify/core": "latest",
142
+ "@axiomify/express": "latest"
143
+ },
144
+ devDependencies: {
145
+ // Keep scaffolded projects on the same TS major as the workspace
146
+ // (^6) so types like `satisfies`, `const` type parameters, etc., don't
147
+ // drift between the framework and user code.
148
+ typescript: "^6.0.0",
149
+ "@types/node": "^22.0.0"
150
+ }
151
+ };
152
+ const tsConfig = {
153
+ compilerOptions: {
154
+ target: "ES2022",
155
+ module: "CommonJS",
156
+ moduleResolution: "node",
157
+ strict: true,
158
+ esModuleInterop: true,
159
+ skipLibCheck: true,
160
+ forceConsistentCasingInFileNames: true,
161
+ outDir: "./dist"
162
+ },
163
+ include: ["src/**/*"]
164
+ };
165
+ const indexTs = `import { Axiomify, z } from '@axiomify/core';
166
+ import { ExpressAdapter } from '@axiomify/express';
167
+
168
+ // Exporting the app instance is required for the 'axiomify routes' CLI command
169
+ export const app = new Axiomify();
170
+
171
+ app.route({
172
+ method: 'GET',
173
+ path: '/health',
174
+ handler: async (req, res) => {
175
+ res.status(200).send({ status: 'healthy', timestamp: Date.now() }, 'System Operational');
176
+ }
177
+ });
178
+
179
+ // Prevent listening during CLI inspection
180
+ if (require.main === module) {
181
+ const adapter = new ExpressAdapter(app);
182
+ adapter.listen(3000, () => console.log('\u{1F680} Axiomify engine online on port 3000'));
183
+ }
184
+ `;
185
+ await fs2.writeFile(
186
+ path4.join(dir, "package.json"),
187
+ JSON.stringify(pkgJson, null, 2)
188
+ );
189
+ await fs2.writeFile(
190
+ path4.join(dir, "tsconfig.json"),
191
+ JSON.stringify(tsConfig, null, 2)
192
+ );
193
+ await fs2.writeFile(path4.join(dir, "src", "index.ts"), indexTs);
194
+ console.log(`\u2705 Axiomify project initialized in ${dir}`);
195
+ console.log(`\u{1F4E6} Run 'npm install' to install dependencies.`);
196
+ }
197
+ async function inspectRoutes(entry) {
198
+ const entryPath = path4.resolve(process.cwd(), entry);
199
+ const tempPath = path4.resolve(process.cwd(), ".axiomify/inspect.cjs");
200
+ const userExternals = getUserExternals(process.cwd());
201
+ try {
202
+ await esbuild.build({
203
+ entryPoints: [entryPath],
204
+ bundle: true,
205
+ platform: "node",
206
+ format: "cjs",
207
+ outfile: tempPath,
208
+ external: [.../* @__PURE__ */ new Set([...userExternals, "node:*"])]
209
+ });
210
+ try {
211
+ delete __require.cache[__require.resolve(tempPath)];
212
+ } catch (e) {
213
+ }
214
+ const mod = __require(tempPath);
215
+ const app = mod.app || mod.default;
216
+ if (!app || typeof app.registeredRoutes === "undefined") {
217
+ console.error("\u274C Error: Could not find an exported Axiomify instance.");
218
+ console.error(
219
+ "Ensure your entry file exports the app: `export const app = new Axiomify();`"
220
+ );
221
+ process.exit(1);
222
+ }
223
+ console.log("\n\u{1F9ED} Registered Axiomify Routes:");
224
+ console.log("----------------------------------------------------");
225
+ console.log(`${"METHOD".padEnd(10)} | ${"PATH".padEnd(30)} | VALIDATION`);
226
+ console.log("----------------------------------------------------");
227
+ app.registeredRoutes.forEach((route) => {
228
+ const schemas = [];
229
+ if (route.schema?.body) schemas.push("Body");
230
+ if (route.schema?.query) schemas.push("Query");
231
+ if (route.schema?.params) schemas.push("Params");
232
+ if (route.schema?.response) schemas.push("Response");
233
+ if (route.schema?.files) schemas.push("Files");
234
+ const validationStr = schemas.length > 0 ? schemas.join(", ") : "None";
235
+ console.log(
236
+ `${route.method.padEnd(10)} | ${route.path.padEnd(
237
+ 30
238
+ )} | ${validationStr}`
239
+ );
240
+ });
241
+ console.log("----------------------------------------------------\n");
242
+ } catch (error) {
243
+ console.error("\u274C Failed to inspect routes:", error);
244
+ } finally {
245
+ await fs2.rm(path4.dirname(tempPath), { recursive: true, force: true }).catch(() => {
246
+ });
247
+ }
248
+ }
249
+
250
+ // src/index.ts
251
+ var program = new Command();
252
+ program.name("axiomify").description("The official CLI for the Axiomify framework").version("1.0.0");
253
+ program.command("init").description("Bootstrap a new Axiomify project").argument("[directory]", "Target directory", ".").option("-f, --force", "Overwrite existing project files", false).action((directory, options) => initProject(directory, options));
254
+ program.command("dev").description("Start the development server with hot-reload").argument("[entry]", "Entry file", "src/index.ts").action(devServer);
255
+ program.command("build").description("Compile the application for production").argument("[entry]", "Entry file", "src/index.ts").action(buildProject);
256
+ program.command("routes").description("Inspect and list all registered routes in the application").argument("[entry]", "Entry file", "src/index.ts").action(inspectRoutes);
257
+ program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomify/cli",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "bin": {
5
5
  "axiomify": "./dist/index.js"
6
6
  },
@@ -11,11 +11,22 @@
11
11
  "access": "public"
12
12
  },
13
13
  "scripts": {
14
- "build": "tsc"
14
+ "build": "tsup"
15
15
  },
16
16
  "dependencies": {
17
17
  "@axiomify/core": "*",
18
- "commander": "^12.0.0",
19
- "esbuild": "^0.20.1"
18
+ "commander": "12.0.0",
19
+ "esbuild": "0.20.1"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.mjs",
25
+ "require": "./dist/index.js"
26
+ }
27
+ },
28
+ "module": "./dist/index.mjs",
29
+ "engines": {
30
+ "node": ">=18.0.0"
20
31
  }
21
32
  }
@@ -1 +0,0 @@
1
- export declare function buildProject(entry: string): Promise<void>;
@@ -1,65 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.buildProject = buildProject;
40
- const esbuild = __importStar(require("esbuild"));
41
- const path_1 = __importDefault(require("path"));
42
- const externals_1 = require("../utils/externals");
43
- async function buildProject(entry) {
44
- const entryPath = path_1.default.resolve(process.cwd(), entry);
45
- const outPath = path_1.default.resolve(process.cwd(), 'dist/index.js');
46
- const userExternals = (0, externals_1.getUserExternals)(process.cwd());
47
- console.log(`šŸ”Ø Building production bundle from ${entry}...`);
48
- try {
49
- await esbuild.build({
50
- entryPoints: [entryPath],
51
- bundle: true,
52
- platform: 'node',
53
- target: 'node18',
54
- outfile: outPath,
55
- minify: true,
56
- keepNames: true,
57
- external: [...new Set([...userExternals, 'node:*'])],
58
- });
59
- console.log(`āœ… Build successful: ${outPath}`);
60
- }
61
- catch (error) {
62
- console.error('āŒ Build failed:', error);
63
- process.exit(1);
64
- }
65
- }
@@ -1 +0,0 @@
1
- export declare function devServer(entry: string): Promise<void>;
@@ -1,88 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.devServer = devServer;
40
- const child_process_1 = require("child_process");
41
- const esbuild = __importStar(require("esbuild"));
42
- const path_1 = __importDefault(require("path"));
43
- const externals_1 = require("../utils/externals");
44
- async function devServer(entry) {
45
- const entryPath = path_1.default.resolve(process.cwd(), entry);
46
- const outPath = path_1.default.resolve(process.cwd(), '.axiomify/dev.js');
47
- let child = null;
48
- const restartServer = () => {
49
- if (child) {
50
- // 1. Stop listening to old exit events so we don't accidentally spawn twice
51
- child.removeAllListeners('exit');
52
- // 2. ONLY spawn the new server after the old one has completely exited
53
- child.once('exit', () => {
54
- child = (0, child_process_1.spawn)('node', [outPath], { stdio: 'inherit' });
55
- });
56
- // 3. Ruthlessly kill the old server (bypasses graceful shutdown)
57
- child.kill('SIGKILL');
58
- }
59
- else {
60
- // First time booting up
61
- child = (0, child_process_1.spawn)('node', [outPath], { stdio: 'inherit' });
62
- }
63
- };
64
- const watchPlugin = {
65
- name: 'watch-plugin',
66
- setup(build) {
67
- build.onEnd((result) => {
68
- if (result.errors.length > 0) {
69
- console.error('āŒ Build failed. Waiting for changes...');
70
- }
71
- else {
72
- restartServer();
73
- }
74
- });
75
- },
76
- };
77
- const userExternals = await (0, externals_1.getUserExternals)(process.cwd());
78
- const ctx = await esbuild.context({
79
- entryPoints: [entryPath],
80
- bundle: true,
81
- platform: 'node',
82
- outfile: outPath,
83
- external: [...new Set([...userExternals, 'node:*'])],
84
- plugins: [watchPlugin],
85
- });
86
- console.log(`šŸ‘€ Axiomify Dev Engine watching for changes...`);
87
- await ctx.watch();
88
- }
@@ -1 +0,0 @@
1
- export declare function initProject(targetDir: string): Promise<void>;
@@ -1,69 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.initProject = initProject;
7
- const promises_1 = __importDefault(require("fs/promises"));
8
- const path_1 = __importDefault(require("path"));
9
- async function initProject(targetDir) {
10
- const dir = path_1.default.resolve(process.cwd(), targetDir);
11
- await promises_1.default.mkdir(path_1.default.join(dir, 'src'), { recursive: true });
12
- const pkgJson = {
13
- name: 'axiomify-app',
14
- version: '1.0.0',
15
- private: true,
16
- scripts: {
17
- dev: 'axiomify dev src/index.ts',
18
- build: 'axiomify build src/index.ts',
19
- start: 'node dist/index.js',
20
- routes: 'axiomify routes src/index.ts',
21
- },
22
- dependencies: {
23
- '@axiomify/core': 'latest',
24
- '@axiomify/express': 'latest',
25
- },
26
- devDependencies: {
27
- typescript: '^5.0.0',
28
- '@types/node': '^20.0.0',
29
- },
30
- };
31
- const tsConfig = {
32
- compilerOptions: {
33
- target: 'ES2022',
34
- module: 'CommonJS',
35
- moduleResolution: 'node',
36
- strict: true,
37
- esModuleInterop: true,
38
- skipLibCheck: true,
39
- forceConsistentCasingInFileNames: true,
40
- outDir: './dist',
41
- },
42
- include: ['src/**/*'],
43
- };
44
- const indexTs = `import { Axiomify, z } from '@axiomify/core';
45
- import { ExpressAdapter } from '@axiomify/express';
46
-
47
- // Exporting the app instance is required for the 'axiomify routes' CLI command
48
- export const app = new Axiomify();
49
-
50
- app.route({
51
- method: 'GET',
52
- path: '/health',
53
- handler: async (req, res) => {
54
- res.status(200).send({ status: 'healthy', timestamp: Date.now() }, 'System Operational');
55
- }
56
- });
57
-
58
- // Prevent listening during CLI inspection
59
- if (require.main === module) {
60
- const adapter = new ExpressAdapter(app);
61
- adapter.listen(3000, () => console.log('šŸš€ Axiomify engine online on port 3000'));
62
- }
63
- `;
64
- await promises_1.default.writeFile(path_1.default.join(dir, 'package.json'), JSON.stringify(pkgJson, null, 2));
65
- await promises_1.default.writeFile(path_1.default.join(dir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
66
- await promises_1.default.writeFile(path_1.default.join(dir, 'src', 'index.ts'), indexTs);
67
- console.log(`āœ… Axiomify project initialized in ${dir}`);
68
- console.log(`šŸ“¦ Run 'npm install' to install dependencies.`);
69
- }
@@ -1 +0,0 @@
1
- export declare function inspectRoutes(entry: string): Promise<void>;
@@ -1,106 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.inspectRoutes = inspectRoutes;
40
- const esbuild = __importStar(require("esbuild"));
41
- const promises_1 = __importDefault(require("fs/promises"));
42
- const path_1 = __importDefault(require("path"));
43
- const externals_1 = require("../utils/externals");
44
- async function inspectRoutes(entry) {
45
- const entryPath = path_1.default.resolve(process.cwd(), entry);
46
- const tempPath = path_1.default.resolve(process.cwd(), '.axiomify/inspect.cjs');
47
- const userExternals = (0, externals_1.getUserExternals)(process.cwd());
48
- try {
49
- // 1. Compile the app to a temporary CommonJS file
50
- await esbuild.build({
51
- entryPoints: [entryPath],
52
- bundle: true,
53
- platform: 'node',
54
- format: 'cjs',
55
- outfile: tempPath,
56
- external: [...new Set([...userExternals, 'node:*'])],
57
- });
58
- // 2. Clear require cache to ensure fresh load
59
- try {
60
- delete require.cache[require.resolve(tempPath)];
61
- }
62
- catch (e) {
63
- // Ignore if it's the first time and not yet in cache
64
- }
65
- // 3. Import the compiled app
66
- // Since the CLI is CJS, import() becomes require().
67
- // require() uses raw absolute paths, not file:// URLs.
68
- const mod = require(tempPath);
69
- const app = mod.app || mod.default;
70
- if (!app || typeof app.registeredRoutes === 'undefined') {
71
- console.error('āŒ Error: Could not find an exported Axiomify instance.');
72
- console.error('Ensure your entry file exports the app: `export const app = new Axiomify();`');
73
- process.exit(1);
74
- }
75
- // 4. Format and print the routes
76
- console.log('\n🧭 Registered Axiomify Routes:');
77
- console.log('----------------------------------------------------');
78
- console.log(`${'METHOD'.padEnd(10)} | ${'PATH'.padEnd(30)} | VALIDATION`);
79
- console.log('----------------------------------------------------');
80
- app.registeredRoutes.forEach((route) => {
81
- const schemas = [];
82
- if (route.schema?.body)
83
- schemas.push('Body');
84
- if (route.schema?.query)
85
- schemas.push('Query');
86
- if (route.schema?.params)
87
- schemas.push('Params');
88
- if (route.schema?.response)
89
- schemas.push('Response');
90
- if (route.schema?.files)
91
- schemas.push('Files');
92
- const validationStr = schemas.length > 0 ? schemas.join(', ') : 'None';
93
- console.log(`${route.method.padEnd(10)} | ${route.path.padEnd(30)} | ${validationStr}`);
94
- });
95
- console.log('----------------------------------------------------\n');
96
- }
97
- catch (error) {
98
- console.error('āŒ Failed to inspect routes:', error);
99
- }
100
- finally {
101
- // 5. Cleanup temp file
102
- await promises_1.default
103
- .rm(path_1.default.dirname(tempPath), { recursive: true, force: true })
104
- .catch(() => { });
105
- }
106
- }
@@ -1 +0,0 @@
1
- export declare function getUserExternals(cwd: string): string[];
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getUserExternals = getUserExternals;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- function getUserExternals(cwd) {
10
- try {
11
- const pkgPath = path_1.default.join(cwd, 'package.json');
12
- if (fs_1.default.existsSync(pkgPath)) {
13
- const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
14
- const deps = Object.keys(pkg.dependencies || {});
15
- const devDeps = Object.keys(pkg.devDependencies || {});
16
- return [...deps, ...devDeps];
17
- }
18
- }
19
- catch (err) {
20
- console.warn('[Axiomify CLI] Failed to read package.json, defaulting to empty externals.');
21
- }
22
- return [];
23
- }