atmx-cli 0.44.0 → 0.48.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.
@@ -28,6 +28,17 @@ function generateSdk(multiIr, isReact = false) {
28
28
  lines.push(` public readonly ${(0, utils_1.camelCase)(ns)} = new ${(0, utils_1.pascalCase)(ns)}Module();`);
29
29
  }
30
30
  lines.push(`}\nexport const sdk = new AxiomSdk();`);
31
+ lines.push(`\nexport const AxiomDefaultConfig = {`);
32
+ lines.push(` contracts: {`);
33
+ for (const ns of Object.keys(multiIr)) {
34
+ lines.push(` "${ns}": {`);
35
+ lines.push(` contractUrl: "/${ns}.axiom",`);
36
+ lines.push(` baseUrl: "http://localhost:8000" // Override this in production!`);
37
+ lines.push(` },`);
38
+ }
39
+ lines.push(` }`);
40
+ lines.push(`};\n`);
41
+ return lines.join("\n");
31
42
  return lines.join("\n");
32
43
  }
33
44
  function generateEndpointMethod(ep, ns, pascalNs, isReact) {
package/dist/index.js CHANGED
@@ -37,19 +37,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  const commander_1 = require("commander");
38
38
  const fs = __importStar(require("fs-extra"));
39
39
  const path = __importStar(require("path"));
40
+ const toml = __importStar(require("@iarna/toml"));
40
41
  const model_generator_1 = require("./generators/model-generator");
41
42
  const sdk_generator_1 = require("./generators/sdk-generator");
42
43
  const utils_1 = require("./generators/utils");
43
44
  const program = new commander_1.Command();
44
45
  program
45
46
  .name("atmx")
46
- .description("Generate TypeScript SDK from an ATMX Multi-Contract Config")
47
+ .description("Generate TypeScript SDK from AxiomDeps.toml")
47
48
  .version("0.2.0");
48
49
  program
49
50
  .command("generate")
50
- .requiredOption("-c, --config <path>", "Path to the atmx.config.json file")
51
+ .requiredOption("-c, --config <path>", "Path to AxiomDeps.toml")
51
52
  .requiredOption("-o, --output <dir>", "Output directory for generated files")
52
- .option("-r, --react", "Generate React Hooks instead of Vanilla JS strings") // ✨ NEW
53
+ .option("-r, --react", "Generate React Hooks instead of Vanilla JS strings")
53
54
  .action(async (options) => {
54
55
  const configPath = path.resolve(options.config);
55
56
  const outputDir = path.resolve(options.output);
@@ -57,42 +58,32 @@ program
57
58
  console.error(`❌ Error: Config file not found at ${configPath}`);
58
59
  process.exit(1);
59
60
  }
60
- // 1. Read the Config File
61
- const rawConfig = await fs.readJSON(configPath);
61
+ // 1. Read and Parse TOML
62
+ const tomlString = await fs.readFile(configPath, "utf-8");
63
+ const rawConfig = toml.parse(tomlString);
62
64
  if (!rawConfig.contracts || Object.keys(rawConfig.contracts).length === 0) {
63
- console.error("❌ Error: Invalid config file. Missing 'contracts' dictionary.");
65
+ console.error("❌ Error: No contracts defined in AxiomDeps.toml.");
64
66
  process.exit(1);
65
67
  }
66
- const configDir = path.dirname(configPath);
67
68
  const multiIr = {};
68
- // 2. Loop through the contracts and parse the local .axiom files
69
+ const projectRoot = path.dirname(configPath); // Frontend project root
70
+ // 2. Loop through contracts
69
71
  for (const [namespace, contract] of Object.entries(rawConfig.contracts)) {
70
- // Resolve the .axiom file path relative to where the config file is located
71
- // (e.g., if config is in /public, and file is "./auth.axiom", it looks in /public/auth.axiom)
72
- const axiomFilePath = path.resolve(configDir, contract.file);
72
+ // Rust CLI safely copies files to `public/[namespace].axiom`
73
+ const axiomFilePath = path.resolve(projectRoot, `public/${namespace}.axiom`);
73
74
  if (!fs.existsSync(axiomFilePath)) {
74
- console.warn(`⚠️ Warning: Contract file not found for namespace '${namespace}' at ${axiomFilePath}. Skipping...`);
75
+ console.warn(`⚠️ Warning: Contract file not found at ${axiomFilePath}. Skipping...`);
75
76
  continue;
76
77
  }
77
78
  const rawFile = await fs.readJSON(axiomFilePath);
78
- if (!rawFile.ir) {
79
- console.warn(`⚠️ Warning: Invalid .axiom file for namespace '${namespace}'. Missing 'ir' property. Skipping...`);
79
+ if (!rawFile.ir)
80
80
  continue;
81
- }
82
- // Normalize the IR (snake_case -> camelCase) and store it by namespace
83
81
  multiIr[namespace] = (0, utils_1.normalizeIr)(rawFile.ir);
84
- console.log(`✅ Loaded contract: [${namespace}] -> ${contract.file}`);
85
- }
86
- if (Object.keys(multiIr).length === 0) {
87
- console.error("❌ Error: No valid contracts were loaded. Aborting generation.");
88
- process.exit(1);
82
+ console.log(`✅ Loaded contract: [${namespace}] -> ${axiomFilePath}`);
89
83
  }
90
- // Ensure output directory exists
91
84
  await fs.ensureDir(outputDir);
92
- // 3. Pass the MultiIR Map to the generators
93
85
  const modelsContent = (0, model_generator_1.generateModels)(multiIr);
94
86
  await fs.writeFile(path.join(outputDir, "models.ts"), modelsContent);
95
- // ✨ NEW: Pass the react flag down
96
87
  const sdkContent = (0, sdk_generator_1.generateSdk)(multiIr, options.react);
97
88
  await fs.writeFile(path.join(outputDir, "sdk.ts"), sdkContent);
98
89
  console.log(`\n🎉 ATMX Multi-Contract SDK generated successfully in ${outputDir}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atmx-cli",
3
- "version": "0.44.0",
3
+ "version": "0.48.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -14,11 +14,13 @@
14
14
  "license": "ISC",
15
15
  "type": "commonjs",
16
16
  "dependencies": {
17
+ "@iarna/toml": "^2.2.5",
17
18
  "commander": "^14.0.3",
18
19
  "fs-extra": "^11.3.4"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@types/fs-extra": "^11.0.4",
23
+ "@types/iarna__toml": "^2.0.5",
22
24
  "@types/node": "^25.5.0",
23
25
  "ts-node": "^10.9.2",
24
26
  "typescript": "^5.9.3"
@@ -39,6 +39,21 @@ export function generateSdk(
39
39
  }
40
40
  lines.push(`}\nexport const sdk = new AxiomSdk();`);
41
41
 
42
+ lines.push(`\nexport const AxiomDefaultConfig = {`);
43
+ lines.push(` contracts: {`);
44
+ for (const ns of Object.keys(multiIr)) {
45
+ lines.push(` "${ns}": {`);
46
+ lines.push(` contractUrl: "/${ns}.axiom",`);
47
+ lines.push(
48
+ ` baseUrl: "http://localhost:8000" // Override this in production!`,
49
+ );
50
+ lines.push(` },`);
51
+ }
52
+ lines.push(` }`);
53
+ lines.push(`};\n`);
54
+
55
+ return lines.join("\n");
56
+
42
57
  return lines.join("\n");
43
58
  }
44
59
 
package/src/index.ts CHANGED
@@ -2,7 +2,8 @@
2
2
  import { Command } from "commander";
3
3
  import * as fs from "fs-extra";
4
4
  import * as path from "path";
5
- import { AtmxMultiConfig, MultiIR } from "./types";
5
+ import * as toml from "@iarna/toml";
6
+ import { MultiIR } from "./types";
6
7
  import { generateModels } from "./generators/model-generator";
7
8
  import { generateSdk } from "./generators/sdk-generator";
8
9
  import { normalizeIr } from "./generators/utils";
@@ -11,14 +12,14 @@ const program = new Command();
11
12
 
12
13
  program
13
14
  .name("atmx")
14
- .description("Generate TypeScript SDK from an ATMX Multi-Contract Config")
15
+ .description("Generate TypeScript SDK from AxiomDeps.toml")
15
16
  .version("0.2.0");
16
17
 
17
18
  program
18
19
  .command("generate")
19
- .requiredOption("-c, --config <path>", "Path to the atmx.config.json file")
20
+ .requiredOption("-c, --config <path>", "Path to AxiomDeps.toml")
20
21
  .requiredOption("-o, --output <dir>", "Output directory for generated files")
21
- .option("-r, --react", "Generate React Hooks instead of Vanilla JS strings") // ✨ NEW
22
+ .option("-r, --react", "Generate React Hooks instead of Vanilla JS strings")
22
23
  .action(async (options) => {
23
24
  const configPath = path.resolve(options.config);
24
25
  const outputDir = path.resolve(options.output);
@@ -28,61 +29,45 @@ program
28
29
  process.exit(1);
29
30
  }
30
31
 
31
- // 1. Read the Config File
32
- const rawConfig: AtmxMultiConfig = await fs.readJSON(configPath);
32
+ // 1. Read and Parse TOML
33
+ const tomlString = await fs.readFile(configPath, "utf-8");
34
+ const rawConfig = toml.parse(tomlString) as any;
33
35
 
34
36
  if (!rawConfig.contracts || Object.keys(rawConfig.contracts).length === 0) {
35
- console.error(
36
- "❌ Error: Invalid config file. Missing 'contracts' dictionary.",
37
- );
37
+ console.error("❌ Error: No contracts defined in AxiomDeps.toml.");
38
38
  process.exit(1);
39
39
  }
40
40
 
41
- const configDir = path.dirname(configPath);
42
41
  const multiIr: MultiIR = {};
42
+ const projectRoot = path.dirname(configPath); // Frontend project root
43
43
 
44
- // 2. Loop through the contracts and parse the local .axiom files
44
+ // 2. Loop through contracts
45
45
  for (const [namespace, contract] of Object.entries(rawConfig.contracts)) {
46
- // Resolve the .axiom file path relative to where the config file is located
47
- // (e.g., if config is in /public, and file is "./auth.axiom", it looks in /public/auth.axiom)
48
- const axiomFilePath = path.resolve(configDir, contract.file);
46
+ // Rust CLI safely copies files to `public/[namespace].axiom`
47
+ const axiomFilePath = path.resolve(
48
+ projectRoot,
49
+ `public/${namespace}.axiom`,
50
+ );
49
51
 
50
52
  if (!fs.existsSync(axiomFilePath)) {
51
53
  console.warn(
52
- `⚠️ Warning: Contract file not found for namespace '${namespace}' at ${axiomFilePath}. Skipping...`,
54
+ `⚠️ Warning: Contract file not found at ${axiomFilePath}. Skipping...`,
53
55
  );
54
56
  continue;
55
57
  }
56
58
 
57
59
  const rawFile = await fs.readJSON(axiomFilePath);
60
+ if (!rawFile.ir) continue;
58
61
 
59
- if (!rawFile.ir) {
60
- console.warn(
61
- `⚠️ Warning: Invalid .axiom file for namespace '${namespace}'. Missing 'ir' property. Skipping...`,
62
- );
63
- continue;
64
- }
65
-
66
- // Normalize the IR (snake_case -> camelCase) and store it by namespace
67
62
  multiIr[namespace] = normalizeIr(rawFile.ir);
68
- console.log(`✅ Loaded contract: [${namespace}] -> ${contract.file}`);
69
- }
70
-
71
- if (Object.keys(multiIr).length === 0) {
72
- console.error(
73
- "❌ Error: No valid contracts were loaded. Aborting generation.",
74
- );
75
- process.exit(1);
63
+ console.log(`✅ Loaded contract: [${namespace}] -> ${axiomFilePath}`);
76
64
  }
77
65
 
78
- // Ensure output directory exists
79
66
  await fs.ensureDir(outputDir);
80
67
 
81
- // 3. Pass the MultiIR Map to the generators
82
68
  const modelsContent = generateModels(multiIr);
83
69
  await fs.writeFile(path.join(outputDir, "models.ts"), modelsContent);
84
70
 
85
- // ✨ NEW: Pass the react flag down
86
71
  const sdkContent = generateSdk(multiIr, options.react);
87
72
  await fs.writeFile(path.join(outputDir, "sdk.ts"), sdkContent);
88
73