atmx-cli 0.54.0 → 0.56.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.
|
@@ -9,13 +9,30 @@ function generateSdk(multiIr, isReact = false) {
|
|
|
9
9
|
`import * as models from './models';\n`,
|
|
10
10
|
];
|
|
11
11
|
if (isReact) {
|
|
12
|
-
|
|
12
|
+
// ✨ FIX: Auto-import the auth helpers to bind them to the module
|
|
13
|
+
lines.push(`import { useAxiomQuery, useAxiomMutation, setAuthToken, clearAuthToken } from 'atmx-react';`);
|
|
13
14
|
lines.push(`import type { AxiomQueryDef } from 'atmx-react';\n`);
|
|
14
15
|
}
|
|
15
16
|
for (const [ns, ir] of Object.entries(multiIr)) {
|
|
16
17
|
const camelNs = (0, utils_1.camelCase)(ns);
|
|
17
|
-
// ✨ FIX: Use an object literal instead of a Class to support React Hooks!
|
|
18
18
|
lines.push(`export const ${camelNs}Module = {`);
|
|
19
|
+
// ✨ FIX: Safely bind auth tokens using the EXACT namespace string from the TOML file!
|
|
20
|
+
if (isReact) {
|
|
21
|
+
lines.push(` setAuthToken(methodName: string, token: string) {`);
|
|
22
|
+
lines.push(` setAuthToken("${ns}", methodName, token);`);
|
|
23
|
+
lines.push(` },`);
|
|
24
|
+
lines.push(` clearAuthToken(methodName: string) {`);
|
|
25
|
+
lines.push(` clearAuthToken("${ns}", methodName);`);
|
|
26
|
+
lines.push(` },`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
lines.push(` setAuthToken(methodName: string, token: string) {`);
|
|
30
|
+
lines.push(` (window as any).atmx?.setAuthToken("${ns}", methodName, token);`);
|
|
31
|
+
lines.push(` },`);
|
|
32
|
+
lines.push(` clearAuthToken(methodName: string) {`);
|
|
33
|
+
lines.push(` (window as any).atmx?.clearAuthToken("${ns}", methodName);`);
|
|
34
|
+
lines.push(` },`);
|
|
35
|
+
}
|
|
19
36
|
const endpointsMap = ir.endpoints || {};
|
|
20
37
|
const endpoints = Array.isArray(endpointsMap)
|
|
21
38
|
? endpointsMap
|
|
@@ -25,13 +42,11 @@ function generateSdk(multiIr, isReact = false) {
|
|
|
25
42
|
});
|
|
26
43
|
lines.push(`};\n`);
|
|
27
44
|
}
|
|
28
|
-
// Generate main SDK object
|
|
29
45
|
lines.push(`export const sdk = {`);
|
|
30
46
|
for (const ns of Object.keys(multiIr)) {
|
|
31
47
|
lines.push(` ${(0, utils_1.camelCase)(ns)}: ${(0, utils_1.camelCase)(ns)}Module,`);
|
|
32
48
|
}
|
|
33
49
|
lines.push(`};\n`);
|
|
34
|
-
// Generate Config
|
|
35
50
|
lines.push(`export const AxiomDefaultConfig = {`);
|
|
36
51
|
lines.push(` contracts: {`);
|
|
37
52
|
for (const ns of Object.keys(multiIr)) {
|
|
@@ -49,14 +64,38 @@ function generateEndpointMethod(ep, ns, camelNs, isReact) {
|
|
|
49
64
|
const params = Array.isArray(rawParams)
|
|
50
65
|
? rawParams
|
|
51
66
|
: Object.values(rawParams);
|
|
52
|
-
const argType = params.length > 0
|
|
53
|
-
? `{ ${params.map((p) => `${(0, utils_1.camelCase)(p.name)}${p.isOptional ? "?" : ""}: ${prefixModels((0, utils_1.mapTypeToTs)(p.typeRef, camelNs))}`).join(", ")} }`
|
|
54
|
-
: "void";
|
|
55
67
|
const isQuery = ep.method ? ep.method.toUpperCase() === "GET" : true;
|
|
56
68
|
const rawReturnType = (0, utils_1.mapTypeToTs)(ep.returnType, camelNs);
|
|
57
69
|
const returnType = rawReturnType === "void" || rawReturnType === "any"
|
|
58
70
|
? rawReturnType
|
|
59
71
|
: prefixModels(rawReturnType);
|
|
72
|
+
// ✨ FIX: If no parameters are defined, default to accepting an optional Record<string, any>
|
|
73
|
+
// This allows developers to pass undocumented fields (like FastAPI Form data)
|
|
74
|
+
if (params.length === 0) {
|
|
75
|
+
if (isReact) {
|
|
76
|
+
const decLogic = generateLambda(ep.returnType, "fromJson", camelNs);
|
|
77
|
+
return `
|
|
78
|
+
get${(0, utils_1.pascalCase)(ep.name)}Def(args?: Record<string, any>): AxiomQueryDef<${returnType}> {
|
|
79
|
+
return {
|
|
80
|
+
namespace: "${ns}", name: "${ep.name}", endpointId: ${ep.id},
|
|
81
|
+
method: "${ep.method ? ep.method.toUpperCase() : "GET"}", path: "${ep.path}",
|
|
82
|
+
args: args || {}, decoder: ${decLogic}, serializer: (p: any) => p, isStream: ${ep.isStream === true}
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
use${(0, utils_1.pascalCase)(ep.name)}${!isQuery ? "Mutation" : ""}(options?: { enabled?: boolean }) {
|
|
86
|
+
${isQuery ? `return useAxiomQuery<${returnType}>(this.get${(0, utils_1.pascalCase)(ep.name)}Def(), options);` : `return useAxiomMutation<${returnType}, void | Record<string,any>>((a) => this.get${(0, utils_1.pascalCase)(ep.name)}Def(a));`}
|
|
87
|
+
},`;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return `
|
|
91
|
+
${(0, utils_1.camelCase)(ep.name)}(args?: Record<string, any>): string {
|
|
92
|
+
const argsStr = args && Object.keys(args).length > 0 ? JSON.stringify(args) : '';
|
|
93
|
+
return \`${ns}.${ep.name}(\${argsStr})\`;
|
|
94
|
+
},`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Endpoints with explicitly defined parameters
|
|
98
|
+
const argType = `{ ${params.map((p) => `${(0, utils_1.camelCase)(p.name)}${p.isOptional ? "?" : ""}: ${prefixModels((0, utils_1.mapTypeToTs)(p.typeRef, camelNs))}`).join(", ")} }`;
|
|
60
99
|
if (isReact) {
|
|
61
100
|
const bodyParam = params.find((p) => p.source === "body");
|
|
62
101
|
const payloadLogic = bodyParam
|
|
@@ -67,31 +106,21 @@ function generateEndpointMethod(ep, ns, camelNs, isReact) {
|
|
|
67
106
|
? generateLambda(bodyParam.typeRef, "toJson", camelNs)
|
|
68
107
|
: `(p: any) => p`;
|
|
69
108
|
return `
|
|
70
|
-
get${(0, utils_1.pascalCase)(ep.name)}Def(args
|
|
109
|
+
get${(0, utils_1.pascalCase)(ep.name)}Def(args?: ${argType}): AxiomQueryDef<${returnType}> {
|
|
71
110
|
${payloadLogic}
|
|
72
111
|
return {
|
|
73
|
-
namespace: "${ns}",
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
method: "${ep.method ? ep.method.toUpperCase() : "GET"}",
|
|
77
|
-
path: "${ep.path}",
|
|
78
|
-
payload: payload,
|
|
79
|
-
args: args || {},
|
|
80
|
-
decoder: ${decLogic},
|
|
81
|
-
serializer: ${serLogic},
|
|
82
|
-
isStream: ${ep.isStream === true}
|
|
112
|
+
namespace: "${ns}", name: "${ep.name}", endpointId: ${ep.id},
|
|
113
|
+
method: "${ep.method ? ep.method.toUpperCase() : "GET"}", path: "${ep.path}",
|
|
114
|
+
payload: payload, args: args || {}, decoder: ${decLogic}, serializer: ${serLogic}, isStream: ${ep.isStream === true}
|
|
83
115
|
};
|
|
84
116
|
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
${isQuery
|
|
88
|
-
? `return useAxiomQuery<${returnType}>(this.get${(0, utils_1.pascalCase)(ep.name)}Def(args), options);`
|
|
89
|
-
: `return useAxiomMutation<${returnType}, ${argType === "void" ? "void | Record<string,any>" : argType}>((args) => this.get${(0, utils_1.pascalCase)(ep.name)}Def(args));`}
|
|
117
|
+
use${(0, utils_1.pascalCase)(ep.name)}${!isQuery ? "Mutation" : ""}(args?: ${argType}, options?: { enabled?: boolean }) {
|
|
118
|
+
${isQuery ? `return useAxiomQuery<${returnType}>(this.get${(0, utils_1.pascalCase)(ep.name)}Def(args), options);` : `return useAxiomMutation<${returnType}, ${argType}>((a) => this.get${(0, utils_1.pascalCase)(ep.name)}Def(a || args));`}
|
|
90
119
|
},`;
|
|
91
120
|
}
|
|
92
121
|
else {
|
|
93
122
|
return `
|
|
94
|
-
${(0, utils_1.camelCase)(ep.name)}(args
|
|
123
|
+
${(0, utils_1.camelCase)(ep.name)}(args?: ${argType}): string {
|
|
95
124
|
const argsStr = args && Object.keys(args).length > 0 ? JSON.stringify(args) : '';
|
|
96
125
|
return \`${ns}.${ep.name}(\${argsStr})\`;
|
|
97
126
|
},`;
|
package/package.json
CHANGED
|
@@ -13,15 +13,38 @@ export function generateSdk(
|
|
|
13
13
|
];
|
|
14
14
|
|
|
15
15
|
if (isReact) {
|
|
16
|
-
|
|
16
|
+
// ✨ FIX: Auto-import the auth helpers to bind them to the module
|
|
17
|
+
lines.push(
|
|
18
|
+
`import { useAxiomQuery, useAxiomMutation, setAuthToken, clearAuthToken } from 'atmx-react';`,
|
|
19
|
+
);
|
|
17
20
|
lines.push(`import type { AxiomQueryDef } from 'atmx-react';\n`);
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
for (const [ns, ir] of Object.entries(multiIr)) {
|
|
21
24
|
const camelNs = camelCase(ns);
|
|
22
|
-
// ✨ FIX: Use an object literal instead of a Class to support React Hooks!
|
|
23
25
|
lines.push(`export const ${camelNs}Module = {`);
|
|
24
26
|
|
|
27
|
+
// ✨ FIX: Safely bind auth tokens using the EXACT namespace string from the TOML file!
|
|
28
|
+
if (isReact) {
|
|
29
|
+
lines.push(` setAuthToken(methodName: string, token: string) {`);
|
|
30
|
+
lines.push(` setAuthToken("${ns}", methodName, token);`);
|
|
31
|
+
lines.push(` },`);
|
|
32
|
+
lines.push(` clearAuthToken(methodName: string) {`);
|
|
33
|
+
lines.push(` clearAuthToken("${ns}", methodName);`);
|
|
34
|
+
lines.push(` },`);
|
|
35
|
+
} else {
|
|
36
|
+
lines.push(` setAuthToken(methodName: string, token: string) {`);
|
|
37
|
+
lines.push(
|
|
38
|
+
` (window as any).atmx?.setAuthToken("${ns}", methodName, token);`,
|
|
39
|
+
);
|
|
40
|
+
lines.push(` },`);
|
|
41
|
+
lines.push(` clearAuthToken(methodName: string) {`);
|
|
42
|
+
lines.push(
|
|
43
|
+
` (window as any).atmx?.clearAuthToken("${ns}", methodName);`,
|
|
44
|
+
);
|
|
45
|
+
lines.push(` },`);
|
|
46
|
+
}
|
|
47
|
+
|
|
25
48
|
const endpointsMap = ir.endpoints || {};
|
|
26
49
|
const endpoints = Array.isArray(endpointsMap)
|
|
27
50
|
? endpointsMap
|
|
@@ -33,14 +56,12 @@ export function generateSdk(
|
|
|
33
56
|
lines.push(`};\n`);
|
|
34
57
|
}
|
|
35
58
|
|
|
36
|
-
// Generate main SDK object
|
|
37
59
|
lines.push(`export const sdk = {`);
|
|
38
60
|
for (const ns of Object.keys(multiIr)) {
|
|
39
61
|
lines.push(` ${camelCase(ns)}: ${camelCase(ns)}Module,`);
|
|
40
62
|
}
|
|
41
63
|
lines.push(`};\n`);
|
|
42
64
|
|
|
43
|
-
// Generate Config
|
|
44
65
|
lines.push(`export const AxiomDefaultConfig = {`);
|
|
45
66
|
lines.push(` contracts: {`);
|
|
46
67
|
for (const ns of Object.keys(multiIr)) {
|
|
@@ -66,11 +87,6 @@ function generateEndpointMethod(
|
|
|
66
87
|
? rawParams
|
|
67
88
|
: Object.values(rawParams);
|
|
68
89
|
|
|
69
|
-
const argType =
|
|
70
|
-
params.length > 0
|
|
71
|
-
? `{ ${params.map((p: any) => `${camelCase(p.name)}${p.isOptional ? "?" : ""}: ${prefixModels(mapTypeToTs(p.typeRef, camelNs))}`).join(", ")} }`
|
|
72
|
-
: "void";
|
|
73
|
-
|
|
74
90
|
const isQuery = ep.method ? ep.method.toUpperCase() === "GET" : true;
|
|
75
91
|
const rawReturnType = mapTypeToTs(ep.returnType, camelNs);
|
|
76
92
|
const returnType =
|
|
@@ -78,6 +94,34 @@ function generateEndpointMethod(
|
|
|
78
94
|
? rawReturnType
|
|
79
95
|
: prefixModels(rawReturnType);
|
|
80
96
|
|
|
97
|
+
// ✨ FIX: If no parameters are defined, default to accepting an optional Record<string, any>
|
|
98
|
+
// This allows developers to pass undocumented fields (like FastAPI Form data)
|
|
99
|
+
if (params.length === 0) {
|
|
100
|
+
if (isReact) {
|
|
101
|
+
const decLogic = generateLambda(ep.returnType, "fromJson", camelNs);
|
|
102
|
+
return `
|
|
103
|
+
get${pascalCase(ep.name)}Def(args?: Record<string, any>): AxiomQueryDef<${returnType}> {
|
|
104
|
+
return {
|
|
105
|
+
namespace: "${ns}", name: "${ep.name}", endpointId: ${ep.id},
|
|
106
|
+
method: "${ep.method ? ep.method.toUpperCase() : "GET"}", path: "${ep.path}",
|
|
107
|
+
args: args || {}, decoder: ${decLogic}, serializer: (p: any) => p, isStream: ${ep.isStream === true}
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
use${pascalCase(ep.name)}${!isQuery ? "Mutation" : ""}(options?: { enabled?: boolean }) {
|
|
111
|
+
${isQuery ? `return useAxiomQuery<${returnType}>(this.get${pascalCase(ep.name)}Def(), options);` : `return useAxiomMutation<${returnType}, void | Record<string,any>>((a) => this.get${pascalCase(ep.name)}Def(a));`}
|
|
112
|
+
},`;
|
|
113
|
+
} else {
|
|
114
|
+
return `
|
|
115
|
+
${camelCase(ep.name)}(args?: Record<string, any>): string {
|
|
116
|
+
const argsStr = args && Object.keys(args).length > 0 ? JSON.stringify(args) : '';
|
|
117
|
+
return \`${ns}.${ep.name}(\${argsStr})\`;
|
|
118
|
+
},`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Endpoints with explicitly defined parameters
|
|
123
|
+
const argType = `{ ${params.map((p: any) => `${camelCase(p.name)}${p.isOptional ? "?" : ""}: ${prefixModels(mapTypeToTs(p.typeRef, camelNs))}`).join(", ")} }`;
|
|
124
|
+
|
|
81
125
|
if (isReact) {
|
|
82
126
|
const bodyParam = params.find(
|
|
83
127
|
(p: any) => p.source === "body",
|
|
@@ -91,32 +135,20 @@ function generateEndpointMethod(
|
|
|
91
135
|
: `(p: any) => p`;
|
|
92
136
|
|
|
93
137
|
return `
|
|
94
|
-
get${pascalCase(ep.name)}Def(args
|
|
138
|
+
get${pascalCase(ep.name)}Def(args?: ${argType}): AxiomQueryDef<${returnType}> {
|
|
95
139
|
${payloadLogic}
|
|
96
140
|
return {
|
|
97
|
-
namespace: "${ns}",
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
method: "${ep.method ? ep.method.toUpperCase() : "GET"}",
|
|
101
|
-
path: "${ep.path}",
|
|
102
|
-
payload: payload,
|
|
103
|
-
args: args || {},
|
|
104
|
-
decoder: ${decLogic},
|
|
105
|
-
serializer: ${serLogic},
|
|
106
|
-
isStream: ${ep.isStream === true}
|
|
141
|
+
namespace: "${ns}", name: "${ep.name}", endpointId: ${ep.id},
|
|
142
|
+
method: "${ep.method ? ep.method.toUpperCase() : "GET"}", path: "${ep.path}",
|
|
143
|
+
payload: payload, args: args || {}, decoder: ${decLogic}, serializer: ${serLogic}, isStream: ${ep.isStream === true}
|
|
107
144
|
};
|
|
108
145
|
},
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
${
|
|
112
|
-
isQuery
|
|
113
|
-
? `return useAxiomQuery<${returnType}>(this.get${pascalCase(ep.name)}Def(args), options);`
|
|
114
|
-
: `return useAxiomMutation<${returnType}, ${argType === "void" ? "void | Record<string,any>" : argType}>((args) => this.get${pascalCase(ep.name)}Def(args));`
|
|
115
|
-
}
|
|
146
|
+
use${pascalCase(ep.name)}${!isQuery ? "Mutation" : ""}(args?: ${argType}, options?: { enabled?: boolean }) {
|
|
147
|
+
${isQuery ? `return useAxiomQuery<${returnType}>(this.get${pascalCase(ep.name)}Def(args), options);` : `return useAxiomMutation<${returnType}, ${argType}>((a) => this.get${pascalCase(ep.name)}Def(a || args));`}
|
|
116
148
|
},`;
|
|
117
149
|
} else {
|
|
118
150
|
return `
|
|
119
|
-
${camelCase(ep.name)}(args
|
|
151
|
+
${camelCase(ep.name)}(args?: ${argType}): string {
|
|
120
152
|
const argsStr = args && Object.keys(args).length > 0 ? JSON.stringify(args) : '';
|
|
121
153
|
return \`${ns}.${ep.name}(\${argsStr})\`;
|
|
122
154
|
},`;
|