atmx-cli 0.47.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.
- package/dist/generators/sdk-generator.js +11 -0
- package/dist/index.js +15 -24
- package/package.json +3 -1
- package/src/generators/sdk-generator.ts +15 -0
- package/src/index.ts +19 -34
|
@@ -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
|
|
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
|
|
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")
|
|
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
|
|
61
|
-
const
|
|
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:
|
|
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
|
-
|
|
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
|
-
//
|
|
71
|
-
|
|
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
|
|
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}] -> ${
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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")
|
|
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
|
|
32
|
-
const
|
|
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
|
|
44
|
+
// 2. Loop through contracts
|
|
45
45
|
for (const [namespace, contract] of Object.entries(rawConfig.contracts)) {
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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}] -> ${
|
|
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
|
|