@axiomify/cli 6.1.0 → 6.2.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/README.md +14 -15
- package/dist/{dist-SYWHGZLI.mjs → dist-IQQ2XGG4.mjs} +30 -10
- package/dist/index.js +2108 -667
- package/dist/index.mjs +2079 -658
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# @axiomify/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
[](https://npmjs.com/package//@axiomify/cli)
|
|
5
4
|
[](https://codecov.io/github/otopman/axiomify)
|
|
6
5
|
[](https://securityscorecards.dev/viewer/?uri=github.com/OTopman/axiomify)
|
|
@@ -23,15 +22,15 @@ the same major as your `@axiomify/*` runtime packages.
|
|
|
23
22
|
|
|
24
23
|
## Commands at a glance
|
|
25
24
|
|
|
26
|
-
| Command
|
|
27
|
-
|
|
28
|
-
| `axiomify init [directory]` | Bootstrap a new project
|
|
29
|
-
| `axiomify dev [entry]`
|
|
30
|
-
| `axiomify build [entry]`
|
|
31
|
-
| `axiomify routes [entry]`
|
|
32
|
-
| `axiomify openapi [entry]`
|
|
33
|
-
| `axiomify check [entry]`
|
|
34
|
-
| `axiomify doctor`
|
|
25
|
+
| Command | Purpose |
|
|
26
|
+
| --------------------------- | ------------------------------------------------ |
|
|
27
|
+
| `axiomify init [directory]` | Bootstrap a new project |
|
|
28
|
+
| `axiomify dev [entry]` | Hot-reload dev server (esbuild watch) |
|
|
29
|
+
| `axiomify build [entry]` | Compile a production bundle to `dist/` |
|
|
30
|
+
| `axiomify routes [entry]` | Inspect every HTTP + WebSocket route |
|
|
31
|
+
| `axiomify openapi [entry]` | Generate the OpenAPI 3.0.3 spec |
|
|
32
|
+
| `axiomify check [entry]` | Static production-readiness audit |
|
|
33
|
+
| `axiomify doctor` | Diagnose the host environment |
|
|
35
34
|
| `axiomify sdk <subcommand>` | Manage, generate, build, validate, and diff SDKs |
|
|
36
35
|
|
|
37
36
|
`[entry]` defaults to `src/index.ts` everywhere it's accepted.
|
|
@@ -66,7 +65,7 @@ hooks can drain, with a SIGKILL fallback after 3 seconds.
|
|
|
66
65
|
|
|
67
66
|
## `axiomify routes`
|
|
68
67
|
|
|
69
|
-
Inspects the app
|
|
68
|
+
Inspects the app _without_ booting a listener. Prints a
|
|
70
69
|
Unicode-bordered table with colour-coded HTTP methods, validation
|
|
71
70
|
badges, OpenAPI tags + `operationId`, plugin count, timeout, and
|
|
72
71
|
deprecation marker.
|
|
@@ -172,12 +171,12 @@ axiomify sdk benchmark
|
|
|
172
171
|
## CI example
|
|
173
172
|
|
|
174
173
|
```yaml
|
|
175
|
-
- run: npx axiomify doctor
|
|
176
|
-
- run: npx axiomify check
|
|
174
|
+
- run: npx axiomify doctor # environment sanity
|
|
175
|
+
- run: npx axiomify check # static readiness audit
|
|
177
176
|
- run: npx axiomify build
|
|
178
177
|
- run: npx axiomify openapi -o ./openapi.json --spec-version "$GITHUB_SHA"
|
|
179
|
-
- run: npx axiomify routes --json > routes.json
|
|
180
|
-
- run: npx axiomify sdk validate ./openapi.json
|
|
178
|
+
- run: npx axiomify routes --json > routes.json # surface snapshot
|
|
179
|
+
- run: npx axiomify sdk validate ./openapi.json # schema verification
|
|
181
180
|
- run: npx axiomify sdk diff old-spec.json ./openapi.json # check breaking changes
|
|
182
181
|
```
|
|
183
182
|
|
|
@@ -64,7 +64,8 @@ var OpenApiGenerator = class {
|
|
|
64
64
|
if (s.callbacks) operation.callbacks = s.callbacks;
|
|
65
65
|
const body = this.extractBody(route);
|
|
66
66
|
if (body) {
|
|
67
|
-
if (s.requestBodyDescription)
|
|
67
|
+
if (s.requestBodyDescription)
|
|
68
|
+
body.description = s.requestBodyDescription;
|
|
68
69
|
operation.requestBody = body;
|
|
69
70
|
}
|
|
70
71
|
paths[openApiPath][method] = operation;
|
|
@@ -78,14 +79,23 @@ var OpenApiGenerator = class {
|
|
|
78
79
|
extractParameters(route) {
|
|
79
80
|
const parameters = [];
|
|
80
81
|
if (route.schema?.params) {
|
|
81
|
-
const paramSchema = zodSchemaToOpenApi(
|
|
82
|
+
const paramSchema = zodSchemaToOpenApi(
|
|
83
|
+
route.schema.params
|
|
84
|
+
);
|
|
82
85
|
const properties = paramSchema.properties ?? {};
|
|
83
86
|
for (const [key, prop] of Object.entries(properties)) {
|
|
84
|
-
parameters.push({
|
|
87
|
+
parameters.push({
|
|
88
|
+
name: key,
|
|
89
|
+
in: "path",
|
|
90
|
+
required: true,
|
|
91
|
+
schema: prop
|
|
92
|
+
});
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
95
|
if (route.schema?.query) {
|
|
88
|
-
const querySchema = zodSchemaToOpenApi(
|
|
96
|
+
const querySchema = zodSchemaToOpenApi(
|
|
97
|
+
route.schema.query
|
|
98
|
+
);
|
|
89
99
|
const properties = querySchema.properties ?? {};
|
|
90
100
|
const required = querySchema.required ?? [];
|
|
91
101
|
for (const [key, prop] of Object.entries(properties)) {
|
|
@@ -129,11 +139,18 @@ var OpenApiGenerator = class {
|
|
|
129
139
|
if (!route.schema?.body && !route.schema?.files) return void 0;
|
|
130
140
|
const hasFiles = !!route.schema.files;
|
|
131
141
|
const contentType = hasFiles ? "multipart/form-data" : "application/json";
|
|
132
|
-
let finalSchema = {
|
|
142
|
+
let finalSchema = {
|
|
143
|
+
type: "object",
|
|
144
|
+
properties: {}
|
|
145
|
+
};
|
|
133
146
|
if (route.schema.body) {
|
|
134
|
-
const bodySchema = zodSchemaToOpenApi(
|
|
147
|
+
const bodySchema = zodSchemaToOpenApi(
|
|
148
|
+
route.schema.body
|
|
149
|
+
);
|
|
135
150
|
if (bodySchema.type === "object") {
|
|
136
|
-
finalSchema.properties = {
|
|
151
|
+
finalSchema.properties = {
|
|
152
|
+
...bodySchema.properties
|
|
153
|
+
};
|
|
137
154
|
if (bodySchema.required) finalSchema.required = bodySchema.required;
|
|
138
155
|
if (bodySchema.additionalProperties !== void 0) {
|
|
139
156
|
finalSchema.additionalProperties = bodySchema.additionalProperties;
|
|
@@ -155,7 +172,10 @@ var OpenApiGenerator = class {
|
|
|
155
172
|
}
|
|
156
173
|
finalSchema.properties = props;
|
|
157
174
|
}
|
|
158
|
-
return {
|
|
175
|
+
return {
|
|
176
|
+
required: true,
|
|
177
|
+
content: { [contentType]: { schema: finalSchema } }
|
|
178
|
+
};
|
|
159
179
|
}
|
|
160
180
|
extractResponses(route) {
|
|
161
181
|
const descriptions = route.schema?.responseDescriptions ?? {};
|
|
@@ -195,7 +215,7 @@ function escapeHtml(s) {
|
|
|
195
215
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
196
216
|
}
|
|
197
217
|
function escapeJsString(s) {
|
|
198
|
-
return s.replace(
|
|
218
|
+
return JSON.stringify(s).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
199
219
|
}
|
|
200
220
|
function defineSecuritySchemes(schemes) {
|
|
201
221
|
return {
|
|
@@ -325,7 +345,7 @@ function useOpenAPI(app, options) {
|
|
|
325
345
|
<script>
|
|
326
346
|
window.onload = () => {
|
|
327
347
|
window.ui = SwaggerUIBundle({
|
|
328
|
-
url:
|
|
348
|
+
url: ${escapeJsString(specUrl)},
|
|
329
349
|
dom_id: '#swagger-ui',
|
|
330
350
|
});
|
|
331
351
|
};
|