@shipworthy/openapi-cli 0.0.0-stage → 0.0.1
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/LICENSE +21 -0
- package/README.md +440 -2
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +19 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +6 -0
- package/dist/commands/bundle/command.d.ts +6 -0
- package/dist/commands/bundle/command.js +23 -0
- package/dist/commands/generate/command.d.ts +2 -0
- package/dist/commands/generate/command.js +6 -0
- package/dist/commands/generate/ensure.d.ts +9 -0
- package/dist/commands/generate/ensure.js +31 -0
- package/dist/commands/generate/files.d.ts +4 -0
- package/dist/commands/generate/files.js +16 -0
- package/dist/commands/generate/force.d.ts +2 -0
- package/dist/commands/generate/force.js +2 -0
- package/dist/commands/generate/plugins/standard-schema/plugin.d.ts +7 -0
- package/dist/commands/generate/plugins/standard-schema/plugin.js +44 -0
- package/dist/commands/generate/plugins/tanstack-query/plugin.d.ts +9 -0
- package/dist/commands/generate/plugins/tanstack-query/plugin.js +42 -0
- package/dist/commands/generate/plugins/typescript/flags.d.ts +35 -0
- package/dist/commands/generate/plugins/typescript/flags.js +37 -0
- package/dist/commands/generate/plugins/typescript/plugin.d.ts +32 -0
- package/dist/commands/generate/plugins/typescript/plugin.js +84 -0
- package/dist/commands/generate/plugins/zod/plugin.d.ts +8 -0
- package/dist/commands/generate/plugins/zod/plugin.js +48 -0
- package/dist/commands/generate/publish.d.ts +11 -0
- package/dist/commands/generate/publish.js +23 -0
- package/dist/commands/generate/stamp.d.ts +13 -0
- package/dist/commands/generate/stamp.js +61 -0
- package/dist/commands/input.d.ts +4 -0
- package/dist/commands/input.js +16 -0
- package/dist/commands/lint/command.d.ts +7 -0
- package/dist/commands/lint/command.js +35 -0
- package/dist/commands/overlay/command.d.ts +9 -0
- package/dist/commands/overlay/command.js +32 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/package.json +72 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shipworthy AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,441 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @shipworthy/openapi-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@shipworthy/openapi-cli` installs the `openapi` command. It bundles, overlays, and lints OpenAPI 3.x documents and generates code from them: TypeScript types, Zod validators, Standard Schema validators, and typed TanStack Query clients. Use it in a build step or `generate` script that keeps generated API code in sync with a local or remote OpenAPI document. Each generator is a separate optional package (`@shipworthy/openapi-typescript`, `@shipworthy/openapi-zod`, `@shipworthy/openapi-standard-schema`, `@shipworthy/openapi-tanstack-query`). The CLI loads a generator only when you run its command, so install just the ones you use.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **Node.js `>=22.19.0` or Bun.** The `openapi` binary is compiled JavaScript (`dist/bin.js`) with a `#!/usr/bin/env node` shebang, and it runs on `@effect/platform-node`. Run it with `bunx --bun @shipworthy/openapi-cli …`.
|
|
8
|
+
- **ESM only.** The package sets `"type": "module"` and ships compiled ESM JavaScript with `.d.ts` declarations. There is no CommonJS build.
|
|
9
|
+
- **Input:** OpenAPI 3.x documents in JSON or YAML. `bundle`, `overlay`, and `generate` upgrade OpenAPI 3.0 documents to 3.1 before writing their output. Swagger 2.0 is rejected.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Install the CLI and the generator packages you need as dev dependencies. The CLI brings its own dependencies (`effect` `^4.0.0`, `@effect/platform-node` `^4.0.0`, `@shipworthy/openapi-generator`, `@shipworthy/openapi-parser`, `@shipworthy/overlay`, and `@shipworthy/openapi-validator`):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
bun add -d @shipworthy/openapi-cli @shipworthy/openapi-typescript effect@^4
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Optional peer dependencies (generators)
|
|
20
|
+
|
|
21
|
+
Install the generator package for each `generate` subcommand you use, at the same version as the CLI:
|
|
22
|
+
|
|
23
|
+
| Command | Requires | Notes |
|
|
24
|
+
| ---------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
25
|
+
| `openapi generate typescript` | `@shipworthy/openapi-typescript` | That package peers on `effect@^4.0.0`. |
|
|
26
|
+
| `openapi generate zod` | `@shipworthy/openapi-zod` and `@shipworthy/openapi-typescript` | Also writes `types.ts`. |
|
|
27
|
+
| `openapi generate tanstack-query` | `@shipworthy/openapi-tanstack-query` and `@shipworthy/openapi-typescript` | Also writes `types.ts`. |
|
|
28
|
+
| `openapi generate standard-schema` | `@shipworthy/openapi-standard-schema` | |
|
|
29
|
+
| `openapi lint` | nothing extra | Bundled through `@shipworthy/openapi-validator` (Spectral). |
|
|
30
|
+
|
|
31
|
+
The generated files import packages at runtime, so your application needs those packages too:
|
|
32
|
+
|
|
33
|
+
| Generated file | Imports |
|
|
34
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
35
|
+
| `types.ts` (TypeScript) | nothing (types only) |
|
|
36
|
+
| Zod output | `zod` (v4; the generator is built against `zod@4.6.5`) and `./types` |
|
|
37
|
+
| Standard Schema output | `effect` (`^4.0.0`) |
|
|
38
|
+
| `client.ts` (TanStack Query) | `@shipworthy/openapi-tanstack-query` (a runtime dependency), which peers on `@tanstack/react-query@^5.104.1` and `react@^18.0.0 \|\| ^19.0.0` |
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
Run the `openapi` commands below in a package script, or use `bunx --bun @shipworthy/openapi-cli` in place of `openapi`.
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
bun add -d @shipworthy/openapi-cli @shipworthy/openapi-typescript effect@^4
|
|
46
|
+
bunx --bun @shipworthy/openapi-cli lint ./openapi.yaml
|
|
47
|
+
bunx --bun @shipworthy/openapi-cli generate typescript ./openapi.yaml -o ./src/generated/types.ts
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Given this `openapi.yaml`:
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
openapi: 3.1.0
|
|
54
|
+
info: { title: Pets, version: 1.0.0 }
|
|
55
|
+
paths:
|
|
56
|
+
/pets:
|
|
57
|
+
get:
|
|
58
|
+
operationId: listPets
|
|
59
|
+
responses:
|
|
60
|
+
"200":
|
|
61
|
+
description: OK
|
|
62
|
+
content:
|
|
63
|
+
application/json:
|
|
64
|
+
schema: { type: array, items: { $ref: "#/components/schemas/Pet" } }
|
|
65
|
+
components:
|
|
66
|
+
schemas:
|
|
67
|
+
Pet:
|
|
68
|
+
type: object
|
|
69
|
+
required: [id]
|
|
70
|
+
properties: { id: { type: integer }, name: { type: string } }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`src/generated/types.ts` starts with:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
/**
|
|
77
|
+
* This file was auto-generated by @shipworthy/openapi-typescript.
|
|
78
|
+
* Do not make direct changes to the file.
|
|
79
|
+
*
|
|
80
|
+
* @shipworthy/openapi-typescript@0.0.1:1ef0db7d…
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
export interface paths {
|
|
84
|
+
"/pets": {
|
|
85
|
+
// …
|
|
86
|
+
get: operations["listPets"];
|
|
87
|
+
// …
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type webhooks = Record<string, never>;
|
|
92
|
+
|
|
93
|
+
export interface components {
|
|
94
|
+
schemas: {
|
|
95
|
+
Pet: {
|
|
96
|
+
id: number;
|
|
97
|
+
name?: string;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
// …
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
A typical `package.json` script that generates a full SDK (from the repository's examples):
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"scripts": {
|
|
109
|
+
"generate": "openapi generate tanstack-query openapi.json -o src/generated --name hotels && openapi generate zod openapi.json -o src/generated/hotels/zod-schema.ts && openapi generate standard-schema openapi.json -o src/generated/hotels/standard-schema.ts"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
That script produces `src/generated/hotels/{types.ts,client.ts,zod-schema.ts,standard-schema.ts}`.
|
|
115
|
+
|
|
116
|
+
## Commands
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
openapi <subcommand> [flags]
|
|
120
|
+
|
|
121
|
+
SUBCOMMANDS
|
|
122
|
+
bundle Bundle an OpenAPI document
|
|
123
|
+
overlay Apply an OpenAPI Overlay
|
|
124
|
+
generate Run a generator plugin
|
|
125
|
+
lint Lint an OpenAPI schema
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Input argument (all commands)
|
|
129
|
+
|
|
130
|
+
Every command takes a positional `<input>`:
|
|
131
|
+
|
|
132
|
+
- A local path, relative to the current directory, e.g. `./openapi.yaml`.
|
|
133
|
+
- An `http:`, `https:`, or `file:` URL. Remote documents are fetched over HTTP, and the response must have a 2xx status.
|
|
134
|
+
- JSON or YAML.
|
|
135
|
+
- **No globs.** An input that contains `*` fails with `Globbing is unsupported.`
|
|
136
|
+
|
|
137
|
+
`bundle`, `overlay`, and `generate` resolve `$ref`s, including references to other files or URLs, before writing their output. `lint` lints the original document text as is, without bundling it.
|
|
138
|
+
|
|
139
|
+
### Global flags
|
|
140
|
+
|
|
141
|
+
These flags come from the Effect CLI framework and work on every command:
|
|
142
|
+
|
|
143
|
+
| Flag | Description |
|
|
144
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
145
|
+
| `--help`, `-h` | Show help for the command. |
|
|
146
|
+
| `--version`, `-v` | Print the CLI version (`openapi v<version>`). |
|
|
147
|
+
| `--wizard` | Start wizard mode for a command. |
|
|
148
|
+
| `--completions <bash\|zsh\|fish\|sh>` | Print a shell completion script. |
|
|
149
|
+
| `--log-level <level>` | Minimum log level: `all`, `trace`, `debug`, `info`, `warn`, `warning`, `error`, `fatal`, `none`. |
|
|
150
|
+
|
|
151
|
+
### `openapi bundle <input> <output>`
|
|
152
|
+
|
|
153
|
+
Bundles an OpenAPI document and writes formatted JSON to the required positional output path. Resolves references to other files or URLs, upgrades OpenAPI 3.0 to 3.1, and validates the result. Requires no generator packages.
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
openapi bundle ./openapi/v1/openapi.yaml ./openapi/v1/bundled.openapi.json
|
|
157
|
+
openapi bundle https://example.com/openapi.yaml ./bundled.openapi.json
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Parent directories are created automatically. An existing output file is overwritten. Loading, reference resolution, validation, or write errors exit with code `1`.
|
|
161
|
+
|
|
162
|
+
### `openapi overlay <input> --overlay <overlay> -o <output>`
|
|
163
|
+
|
|
164
|
+
Bundles the OpenAPI document first, resolving external references and upgrading OpenAPI 3.0 to
|
|
165
|
+
3.1. Then applies an [OpenAPI Overlay 1.1](https://github.com/OAI/Overlay-Specification/blob/main/versions/1.1.0.md)
|
|
166
|
+
and writes formatted JSON. Requires no generator packages. Overlay 1.0 and 1.1 are supported;
|
|
167
|
+
the declared `overlay` version selects validation and action behavior.
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
openapi overlay openapi.yaml --overlay overlay.yaml -o bundled.openapi.json
|
|
171
|
+
openapi overlay https://example.com/openapi.yaml --overlay https://example.com/public.overlay.yaml --output public.openapi.json
|
|
172
|
+
openapi overlay openapi.yaml --overlay selected.overlay.yaml --remove-unused-components -o selected.openapi.json
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
| Argument / flag | Description |
|
|
176
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
177
|
+
| `<input>` | Required OpenAPI JSON/YAML file or URL. |
|
|
178
|
+
| `--overlay` | Required Overlay JSON/YAML file or URL. |
|
|
179
|
+
| `--output`, `-o` | Required output JSON file. Parent directories are created. |
|
|
180
|
+
| `--remove-unused-components` | Optional; defaults to `false`. Remove paths without operations and unreachable components after applying all actions. |
|
|
181
|
+
|
|
182
|
+
Actions run sequentially against the bundled document. Supports RFC 9535 JSONPath, recursive
|
|
183
|
+
object updates, array concatenation/appending, primitive replacement, copying from a single
|
|
184
|
+
source node, and removal. A target matching no nodes has no effect. `extends` is metadata;
|
|
185
|
+
`<input>` determines the document. The overlaid result is written directly without another
|
|
186
|
+
bundling or validation pass.
|
|
187
|
+
|
|
188
|
+
With `--remove-unused-components`, the result is validated as OpenAPI 3.1 and only components
|
|
189
|
+
reachable from retained paths, webhooks, document-level security, and root `$defs` remain. References are
|
|
190
|
+
followed transitively across all component categories, including recursive schemas,
|
|
191
|
+
discriminator mappings and inheritance, and security scheme names. Empty component groups
|
|
192
|
+
are removed. Pruning requires local JSON Pointer references; reachable external/anchor refs
|
|
193
|
+
and `$dynamicRef` fail. Broken references and links to removed operation IDs also fail before
|
|
194
|
+
writing output. See the overlay package's operation filtering example below.
|
|
195
|
+
|
|
196
|
+
An existing output file is overwritten only after bundling, overlay application, and optional pruning succeed.
|
|
197
|
+
Loading, invalid overlay, incompatible merge, JSONPath, pruning, and write errors exit with code `1`.
|
|
198
|
+
Action errors include the one-based action number and target. See the
|
|
199
|
+
[`@shipworthy/overlay` documentation](../openapi-overlay/README.md) for merge rules and errors.
|
|
200
|
+
|
|
201
|
+
### `openapi lint [--strict] <input>`
|
|
202
|
+
|
|
203
|
+
Lints an OpenAPI 3.x document with Spectral's `oas` ruleset and prints diagnostics.
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
openapi lint ./openapi.yaml
|
|
207
|
+
openapi lint https://example.com/openapi.yaml
|
|
208
|
+
openapi lint --strict ./openapi.yaml
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- Warnings print as ` ⚠ <message> at #/<json/pointer>`. Errors print as ` ✘ <message> at #/<json/pointer>`. Colors are used only when stdout is a TTY and `NO_COLOR` is unset.
|
|
212
|
+
- Rules whose `oas` severity is `error` are downgraded to warnings. The exception is `operation-operationId-unique`, so duplicate `operationId`s are an error.
|
|
213
|
+
- `oas3-schema` is turned off. Structural validation belongs to the parser that `generate` uses.
|
|
214
|
+
- `--strict` (default off) keeps Spectral's original `oas` severities, so every `error` rule (for example `path-params`) fails the run, and YAML/JSON syntax errors fail too. `oas3-schema` stays off.
|
|
215
|
+
- **Exit code:** `0` when there are only warnings or no diagnostics. `1` when there is at least one error, and the error messages are repeated under `ERROR`.
|
|
216
|
+
- A document that is not OpenAPI 3.x fails with `Expected an OpenAPI 3.x document`.
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
$ openapi lint dup.yaml
|
|
220
|
+
⚠ Operation must have non-empty "tags" array. at #/paths//a/get
|
|
221
|
+
✘ Every operation must have unique "operationId". at #/paths//b/get/operationId
|
|
222
|
+
|
|
223
|
+
ERROR
|
|
224
|
+
Every operation must have unique "operationId". at #/paths//b/get/operationId
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### `openapi generate typescript [<input>]`
|
|
228
|
+
|
|
229
|
+
Converts an OpenAPI document to TypeScript types (`paths`, `webhooks`, `components`, `operations`, …) and formats the result. Requires `@shipworthy/openapi-typescript`.
|
|
230
|
+
|
|
231
|
+
```sh
|
|
232
|
+
openapi generate typescript ./openapi.yaml -o ./schema.ts
|
|
233
|
+
openapi generate typescript https://example.com/openapi.json > schema.ts
|
|
234
|
+
cat openapi.yaml | openapi generate typescript -o ./schema.ts
|
|
235
|
+
openapi generate typescript ./openapi.yaml -o ./schema.ts --check # CI drift check
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
| Argument / flag | Type | Default | Description |
|
|
239
|
+
| ---------------- | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
240
|
+
| `<input>` | path or URL | stdin | Optional. Reads the document from stdin when omitted. |
|
|
241
|
+
| `--output`, `-o` | file path | stdout | Output file. Parent directories are created. Writes to stdout when omitted. |
|
|
242
|
+
| `--check` | boolean | `false` | Writes nothing. Compares the generated output with the existing `--output` file and exits `1` with `Generated types are not up-to-date!` when they differ. Use it together with `-o`. |
|
|
243
|
+
|
|
244
|
+
Type-generation flags. All are boolean and default to `false` except `--array-length`, which
|
|
245
|
+
defaults to `true`:
|
|
246
|
+
|
|
247
|
+
| Flag | Description |
|
|
248
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
249
|
+
| `--enum` | Export true TS enums instead of unions. |
|
|
250
|
+
| `--enum-values` | Export enum values as arrays. |
|
|
251
|
+
| `--conditional-enums` | Only generate true TS enums when enum metadata is available. |
|
|
252
|
+
| `--dedupe-enums` | Dedupe enum types when `--enum` is set. |
|
|
253
|
+
| `--export-type`, `-t` | Export top-level type aliases instead of interfaces. |
|
|
254
|
+
| `--array-length` | Generate tuples using array `minItems` / `maxItems`. Enabled by default; disable with `--array-length=false` or `--no-array-length`. |
|
|
255
|
+
| `--root-types` | Export component and operation aliases at the root level. Schema aliases have no prefix; operation aliases uppercase the first character of the operation ID. |
|
|
256
|
+
| `--read-write-markers` | Generate `$Read`/`$Write` markers for `readOnly`/`writeOnly` properties. |
|
|
257
|
+
|
|
258
|
+
The output always includes an `ApiPaths` enum with route values. Paths retain their literal
|
|
259
|
+
OpenAPI templates, such as `/pets/{id}`.
|
|
260
|
+
|
|
261
|
+
With `-o`, the command logs `<input> → <output> [<elapsed>]` when it finishes.
|
|
262
|
+
|
|
263
|
+
Use an overlay before generation to require properties, allow additional keys, remove
|
|
264
|
+
deprecated members, or declare path parameters. See the
|
|
265
|
+
[overlay examples](../openapi-overlay/README.md#preparing-a-document-for-generation).
|
|
266
|
+
|
|
267
|
+
```sh
|
|
268
|
+
openapi overlay openapi.yaml --overlay types.overlay.yaml -o types.openapi.json
|
|
269
|
+
openapi generate typescript types.openapi.json -o schema.ts
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### `openapi generate zod <input> -o <file>`
|
|
273
|
+
|
|
274
|
+
Generates Zod validators. Requires `@shipworthy/openapi-zod` and `@shipworthy/openapi-typescript`.
|
|
275
|
+
|
|
276
|
+
```sh
|
|
277
|
+
openapi generate zod ./openapi.yaml -o ./src/generated/hotels/zod-schema.ts
|
|
278
|
+
# writes src/generated/hotels/zod-schema.ts and src/generated/hotels/types.ts
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Argument / flag | Type | Default | Description |
|
|
282
|
+
| ---------------- | ----------- | ---------- | --------------------------------------------------------- |
|
|
283
|
+
| `<input>` | path or URL | (required) | OpenAPI document. |
|
|
284
|
+
| `--output`, `-o` | file path | (required) | Output file. `types.ts` is written to the same directory. |
|
|
285
|
+
| `--force` | boolean | `false` | Regenerate `types.ts` even when its stamp matches. |
|
|
286
|
+
|
|
287
|
+
The output imports `zod` and `type { components } from "./types"`. It exports one validator per component schema, typed as `z.ZodType<components["schemas"][Name]>`, plus `<operationId>RequestBody` validators for request bodies:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { Pet } from "./generated/pets/zod-schema";
|
|
291
|
+
|
|
292
|
+
const pet = Pet.parse(await response.json()); // typed as components["schemas"]["Pet"]
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### `openapi generate tanstack-query <input> -o <dir> --name <name>`
|
|
296
|
+
|
|
297
|
+
Generates a typed API client and TanStack Query helpers. Requires `@shipworthy/openapi-tanstack-query` and `@shipworthy/openapi-typescript`.
|
|
298
|
+
|
|
299
|
+
```sh
|
|
300
|
+
openapi generate tanstack-query ./openapi.yaml -o ./src/generated --name hotels
|
|
301
|
+
# writes src/generated/hotels/client.ts and src/generated/hotels/types.ts
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
| Argument / flag | Type | Default | Description |
|
|
305
|
+
| ---------------- | ----------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
306
|
+
| `<input>` | path or URL | (required) | OpenAPI document. |
|
|
307
|
+
| `--output`, `-o` | directory | (required) | Directory that will contain `<name>/client.ts` and `<name>/types.ts`. |
|
|
308
|
+
| `--name` | string | (required) | Client name. Used as the output subdirectory and, in PascalCase, as the prefix of generated exports. It must start with a letter and contain only letters, numbers, and single `-` or `_` separators (`^[a-zA-Z][a-zA-Z0-9]*(?:[-_][a-zA-Z0-9]+)*$`). |
|
|
309
|
+
| `--force` | boolean | `false` | Regenerate `types.ts` even when its stamp matches. |
|
|
310
|
+
|
|
311
|
+
For `--name hotels`, `client.ts` exports:
|
|
312
|
+
|
|
313
|
+
- `createHotelsApiClient(options)` and the `HotelsApiClient` type.
|
|
314
|
+
- `createHotelsApiQueryUtils(client, options?)`, which returns per-operation helpers (`queryOptions`, `mutationOptions`, `infiniteOptions`) keyed by `operationId`.
|
|
315
|
+
- Type re-exports `HotelsApiPaths`, `HotelsApiComponents`, and `HotelsApiOperations`.
|
|
316
|
+
|
|
317
|
+
A `-` or `_` in the name marks a word boundary: `--name my-pets` gives `createMyPetsApiClient`. The command logs `Generated <path>/client.ts`. Operations need unique `operationId`s.
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import { useQuery } from "@tanstack/react-query";
|
|
321
|
+
import { createHotelsApiClient, createHotelsApiQueryUtils } from "./generated/hotels/client";
|
|
322
|
+
|
|
323
|
+
const client = createHotelsApiClient({
|
|
324
|
+
baseUrl: "https://hotels.example.com",
|
|
325
|
+
authToken: () => getHotelsAccessToken(),
|
|
326
|
+
});
|
|
327
|
+
const hotelsApi = createHotelsApiQueryUtils(client);
|
|
328
|
+
|
|
329
|
+
const hotels = useQuery(
|
|
330
|
+
hotelsApi.getHotels.queryOptions({ input: { query: { country: "US", min_stars: 5 } } }),
|
|
331
|
+
);
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
See the `@shipworthy/openapi-tanstack-query` README for the full runtime API.
|
|
335
|
+
|
|
336
|
+
### `openapi generate standard-schema <input> [-o <file>]`
|
|
337
|
+
|
|
338
|
+
Generates [Standard Schema](https://standardschema.dev) validators backed by Effect `Schema`. Requires `@shipworthy/openapi-standard-schema`. This command does not write `types.ts`.
|
|
339
|
+
|
|
340
|
+
```sh
|
|
341
|
+
openapi generate standard-schema ./openapi.yaml -o ./src/generated/schemas.ts
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
| Argument / flag | Type | Default | Description |
|
|
345
|
+
| ---------------- | ----------- | ---------- | ------------------------------------------- |
|
|
346
|
+
| `<input>` | path or URL | (required) | OpenAPI document. |
|
|
347
|
+
| `--output`, `-o` | file path | stdout | Output file. Writes to stdout when omitted. |
|
|
348
|
+
|
|
349
|
+
For each component schema, the output exports a type and a value with the same name, e.g. `export type Pet = …` and `export const Pet = Schema.toStandardSchemaV1(…)`.
|
|
350
|
+
|
|
351
|
+
## Generated file headers and `types.ts` caching
|
|
352
|
+
|
|
353
|
+
Every generated file starts with a stamped header:
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
/**
|
|
357
|
+
* This file was auto-generated by @shipworthy/openapi-typescript.
|
|
358
|
+
* Do not make direct changes to the file.
|
|
359
|
+
*
|
|
360
|
+
* @shipworthy/openapi-typescript@0.0.1:<sha256 of the schema contents>
|
|
361
|
+
*/
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
The stamp is `<generator package>@<generator version>:<sha256>`. The hash covers the document text, not its location. Reading the same document from stdin, from another path, or from a URL gives the same stamp.
|
|
365
|
+
|
|
366
|
+
`generate zod` and `generate tanstack-query` both need `types.ts`:
|
|
367
|
+
|
|
368
|
+
- The command regenerates `types.ts` only if the file is missing or its stamp differs from the current one. A stamp changes when the schema contents or the `@shipworthy/openapi-typescript` version change. Otherwise the existing `types.ts` is left as is.
|
|
369
|
+
- `--force` always regenerates it.
|
|
370
|
+
- These commands always write `types.ts` with the default type flags. To use custom flags (`--enum`, `--root-types`, …), run `openapi generate typescript` yourself.
|
|
371
|
+
- The main output (`client.ts`, the Zod file) is always overwritten.
|
|
372
|
+
|
|
373
|
+
## Programmatic use
|
|
374
|
+
|
|
375
|
+
The package entry point (`@shipworthy/openapi-cli`) exports one value:
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
export const openapi: Command<"openapi", …>; // an `effect/cli` Command with `bundle`, `overlay`, `generate`, and `lint` subcommands
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Use it to embed the CLI in your own entry point. This example mirrors the package's own binary:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
#!/usr/bin/env node
|
|
385
|
+
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
386
|
+
import { openapi } from "@shipworthy/openapi-cli";
|
|
387
|
+
import { Effect, Layer } from "effect";
|
|
388
|
+
import { Command } from "effect/cli";
|
|
389
|
+
import { FetchHttpClient } from "effect/http";
|
|
390
|
+
|
|
391
|
+
openapi.pipe(
|
|
392
|
+
Command.run({ version: "1.0.0" }), // parses process.argv
|
|
393
|
+
Effect.provide(Layer.mergeAll(NodeServices.layer, FetchHttpClient.layer)),
|
|
394
|
+
NodeRuntime.runMain,
|
|
395
|
+
);
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
This requires `effect` `^4.0.0` and `@effect/platform-node` `^4.0.0`, which the CLI also depends on. Add them to your own `package.json` if your code imports them directly. No other functions or types are exported. For direct access to the generation pipeline, use `@shipworthy/openapi-generator`, `@shipworthy/openapi-parser`, and `@shipworthy/openapi-transformer`.
|
|
399
|
+
|
|
400
|
+
## Errors and exit codes
|
|
401
|
+
|
|
402
|
+
Each failure prints an `ERROR` block to stderr and exits with `1`. Common messages:
|
|
403
|
+
|
|
404
|
+
| Message | Cause |
|
|
405
|
+
| -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
406
|
+
| `Globbing is unsupported.` | `<input>` contains `*`. |
|
|
407
|
+
| `Missing required flag: --name` / `--output` | A required flag is missing. |
|
|
408
|
+
| `Invalid value for flag --name: … --name must start with a letter…` | `--name` does not match the allowed pattern. |
|
|
409
|
+
| `Install <package> to load <export>.` (or a module-resolution error) | The generator package for this command is not installed. |
|
|
410
|
+
| `Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.` | The input is a Swagger 2.0 document. |
|
|
411
|
+
| `Unsupported OpenAPI version: <v>` | The `openapi` field is not a 3.x version. |
|
|
412
|
+
| `NotFound: FileSystem.readFile (<path>)` | The input file does not exist. |
|
|
413
|
+
| `Generated types are not up-to-date!` | `generate typescript --check` found that the output file is out of date. |
|
|
414
|
+
| `Expected an OpenAPI 3.x document` | `lint` was given something other than an OpenAPI 3.x document. |
|
|
415
|
+
|
|
416
|
+
## Limitations
|
|
417
|
+
|
|
418
|
+
- One input per run. Globs are not supported.
|
|
419
|
+
- Only `generate typescript` reads from stdin. Only `generate typescript` and `generate standard-schema` write to stdout.
|
|
420
|
+
- Only `generate typescript` supports `--check`. Only `generate zod` and `generate tanstack-query` support `--force`.
|
|
421
|
+
- `lint` does not resolve external `$ref`s. It lints the document text exactly as given.
|
|
422
|
+
- Lint rules are fixed (Spectral `oas` with the adjustments listed above). Custom rulesets are not supported.
|
|
423
|
+
|
|
424
|
+
## Key facts (for AI agents)
|
|
425
|
+
|
|
426
|
+
- Binary: `openapi` (compiled `dist/bin.js`). Runs on **Node.js `>=22.19.0`** or **Bun** (`bunx --bun @shipworthy/openapi-cli`). ESM only. OpenAPI 3.0 and 3.1 input (3.0 is upgraded), JSON or YAML, as a local path or URL. Swagger 2.0 is rejected.
|
|
427
|
+
- Commands:
|
|
428
|
+
- `openapi overlay <input> --overlay <overlay> -o <output> [--remove-unused-components]`: bundles and upgrades first, then applies actions using the declared Overlay 1.0 or 1.1 version and writes JSON. The optional flag prunes paths without operations and unreachable components after overlaying.
|
|
429
|
+
- `openapi lint [--strict] <input>`: exits 1 only on errors such as duplicate `operationId`. `--strict` also fails on every `error`-severity `oas` rule and on syntax errors.
|
|
430
|
+
- `openapi generate typescript [<input>] [-o file] [--check] [type flags]`: reads stdin when `<input>` is omitted and writes stdout when `-o` is omitted.
|
|
431
|
+
- `openapi generate zod <input> -o <file> [--force]`: also writes `types.ts` in the same directory.
|
|
432
|
+
- `openapi generate tanstack-query <input> -o <dir> --name <name> [--force]`: writes `<dir>/<name>/client.ts` and `<dir>/<name>/types.ts`.
|
|
433
|
+
- `openapi generate standard-schema <input> [-o file]`.
|
|
434
|
+
- Each `generate` subcommand needs its optional peer package installed: `@shipworthy/openapi-typescript` (used by typescript, zod, and tanstack-query), `@shipworthy/openapi-zod`, `@shipworthy/openapi-tanstack-query`, and `@shipworthy/openapi-standard-schema`.
|
|
435
|
+
- `types.ts` is regenerated only when its header stamp (`pkg@version:sha256(schema)`) changes. Pass `--force` to override.
|
|
436
|
+
- Do not edit generated files by hand. Re-run the command instead.
|
|
437
|
+
- The only programmatic export is `openapi`, an `effect/cli` `Command`.
|
|
438
|
+
|
|
439
|
+
## License
|
|
440
|
+
|
|
441
|
+
MIT. See [LICENSE](./LICENSE).
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
// Import modules directly: the package index also loads NodeRedis, which requires `redis`.
|
|
11
|
+
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
12
|
+
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
13
|
+
import { ModuleLoader } from "@shipworthy/openapi-generator";
|
|
14
|
+
import { Effect, Layer } from "effect";
|
|
15
|
+
import { Command } from "effect/cli";
|
|
16
|
+
import { FetchHttpClient } from "effect/http";
|
|
17
|
+
import { openapi } from "./cli.js";
|
|
18
|
+
import { version } from "./version.js";
|
|
19
|
+
version.pipe(Effect.flatMap((version) => openapi.pipe(Command.run({ version }))), Effect.provideService(ModuleLoader, { load: (specifier) => import(__rewriteRelativeImportExtension(specifier, true)) }), Effect.provide(Layer.mergeAll(NodeServices.layer, FetchHttpClient.layer)), NodeRuntime.runMain);
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Command } from "effect/cli";
|
|
2
|
+
export declare const openapi: Command.Command<"openapi", {}, {}, import("effect/cli/CliError").UserError, import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient | import("effect/Path").Path | import("effect/Stdio").Stdio>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Command } from "effect/cli";
|
|
2
|
+
import { bundle } from "./commands/bundle/command.js";
|
|
3
|
+
import { generate } from "./commands/generate/command.js";
|
|
4
|
+
import { lint } from "./commands/lint/command.js";
|
|
5
|
+
import { overlay } from "./commands/overlay/command.js";
|
|
6
|
+
export const openapi = Command.make("openapi").pipe(Command.withDescription("Bundle, overlay, and lint OpenAPI schemas, and generate TypeScript, Zod validators, and typed clients."), Command.withSubcommands([bundle, overlay, generate, lint]));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { FileSystem, Path } from "effect";
|
|
2
|
+
import { Command } from "effect/cli";
|
|
3
|
+
export declare const bundle: Command.Command<"bundle", {
|
|
4
|
+
readonly input: URL;
|
|
5
|
+
readonly output: string;
|
|
6
|
+
}, {}, import("effect/cli/CliError").UserError, FileSystem.FileSystem | import("effect/http/HttpClient").HttpClient | Path.Path>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { bundleDocument } from "@shipworthy/openapi-parser";
|
|
2
|
+
import { Console, Effect, FileSystem, Path, Schema } from "effect";
|
|
3
|
+
import { Argument, Command } from "effect/cli";
|
|
4
|
+
import { asCliError, schemaSource } from "../input.js";
|
|
5
|
+
const run = Effect.fn("bundle")(function* ({ input, output, }) {
|
|
6
|
+
const document = yield* bundleDocument(input);
|
|
7
|
+
const fs = yield* FileSystem.FileSystem;
|
|
8
|
+
const path = yield* Path.Path;
|
|
9
|
+
const outputPath = path.resolve(output);
|
|
10
|
+
yield* fs.makeDirectory(path.dirname(outputPath), { recursive: true });
|
|
11
|
+
const serialized = yield* Schema.encodeEffect(Schema.fromJsonString(Schema.Unknown, { space: 2 }))(document);
|
|
12
|
+
yield* fs.writeFileString(outputPath, `${serialized}\n`);
|
|
13
|
+
yield* Console.log(`${input.href} → ${output}`);
|
|
14
|
+
}, Effect.mapError(asCliError));
|
|
15
|
+
export const bundle = Command.make("bundle", {
|
|
16
|
+
input: Argument.String("input").pipe(Argument.withDescription("OpenAPI schema file or URL."), Argument.mapEffect(schemaSource)),
|
|
17
|
+
output: Argument.String("output").pipe(Argument.withDescription("Output JSON file. Parent directories are created.")),
|
|
18
|
+
}, run).pipe(Command.withDescription("Bundle references and upgrade an OpenAPI document to 3.1 JSON."), Command.withShortDescription("Bundle an OpenAPI document"), Command.withExamples([
|
|
19
|
+
{
|
|
20
|
+
command: "openapi bundle ./openapi/v1/openapi.yaml ./openapi/v1/bundled.openapi.json",
|
|
21
|
+
description: "Write a bundled JSON document for a local schema",
|
|
22
|
+
},
|
|
23
|
+
]));
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Command } from "effect/cli";
|
|
2
|
+
export declare const generate: Command.Command<"generate", {}, {}, import("effect/cli/CliError").UserError, import("effect/Crypto").Crypto | import("effect/Stdio").Stdio | (import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient | import("effect/Path").Path)>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Command } from "effect/cli";
|
|
2
|
+
import { standardSchema } from "./plugins/standard-schema/plugin.js";
|
|
3
|
+
import { tanstackQuery } from "./plugins/tanstack-query/plugin.js";
|
|
4
|
+
import { typescript } from "./plugins/typescript/plugin.js";
|
|
5
|
+
import { zod } from "./plugins/zod/plugin.js";
|
|
6
|
+
export const generate = Command.make("generate").pipe(Command.withDescription("Convert an OpenAPI schema to TypeScript."), Command.withShortDescription("Run a generator plugin"), Command.withSubcommands([typescript, zod, tanstackQuery, standardSchema]));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path } from "effect";
|
|
2
|
+
import { CliError } from "effect/cli";
|
|
3
|
+
export interface EnsureTarget {
|
|
4
|
+
readonly source: URL;
|
|
5
|
+
readonly directory: string;
|
|
6
|
+
readonly started: number;
|
|
7
|
+
readonly force: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const ensureDependencies: (dependencies: readonly string[], target: EnsureTarget) => Effect.Effect<void, import("effect/PlatformError").BadArgument | import("effect/http/HttpClientError").HttpClientError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError | CliError.UserError | import("@shipworthy/openapi-generator").GenerateError, import("effect/Crypto").Crypto | import("effect/Stdio").Stdio | (FileSystem.FileSystem | import("effect/http/HttpClient").HttpClient | Path.Path)>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path } from "effect";
|
|
2
|
+
import { CliError } from "effect/cli";
|
|
3
|
+
import { defaultTypeFlags } from "./plugins/typescript/flags.js";
|
|
4
|
+
import { renderTypescript, typescriptSpecifier } from "./plugins/typescript/plugin.js";
|
|
5
|
+
import { generatorStamp, readStamp } from "./stamp.js";
|
|
6
|
+
export const ensureDependencies = Effect.fn("ensureDependencies")(function* (dependencies, target) {
|
|
7
|
+
yield* Effect.forEach(dependencies, (dependency) => dependency === "typescript"
|
|
8
|
+
? ensureTypescript(target)
|
|
9
|
+
: Effect.fail(new CliError.UserError({ cause: `Unknown generator dependency: ${dependency}.` })), { discard: true });
|
|
10
|
+
});
|
|
11
|
+
const ensureTypescript = Effect.fn("ensureTypescript")(function* (target) {
|
|
12
|
+
const fs = yield* FileSystem.FileSystem;
|
|
13
|
+
const path = yield* Path.Path;
|
|
14
|
+
const typesPath = path.join(target.directory, "types.ts");
|
|
15
|
+
const generator = yield* generatorStamp(typescriptSpecifier, target.source);
|
|
16
|
+
if (!target.force) {
|
|
17
|
+
const types = yield* fs.readFileString(typesPath).pipe(Effect.option);
|
|
18
|
+
if (Option.isSome(types) && readStamp(types.value) === generator.stamp)
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
yield* renderTypescript({
|
|
22
|
+
source: target.source,
|
|
23
|
+
generator,
|
|
24
|
+
outputPath: typesPath,
|
|
25
|
+
flags: defaultTypeFlags,
|
|
26
|
+
check: false,
|
|
27
|
+
label: target.source.href,
|
|
28
|
+
outputLabel: typesPath,
|
|
29
|
+
started: target.started,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path, Schema } from "effect";
|
|
2
|
+
export declare function pascalCase(value: string): string;
|
|
3
|
+
export declare const ClientName: Schema.String;
|
|
4
|
+
export declare const writeGenerated: (directory: string, name: string, files: Record<string, string>) => Effect.Effect<void, import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Console, Effect, FileSystem, Path, Schema } from "effect";
|
|
2
|
+
export function pascalCase(value) {
|
|
3
|
+
return value.replace(/(?:^|[-_])([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
|
|
4
|
+
}
|
|
5
|
+
export const ClientName = Schema.String.pipe(Schema.check(Schema.isPattern(/^[a-zA-Z][a-zA-Z0-9]*(?:[-_][a-zA-Z0-9]+)*$/, {
|
|
6
|
+
message: "--name must start with a letter and contain only letters, numbers, and single hyphen or underscore separators.",
|
|
7
|
+
})));
|
|
8
|
+
export const writeGenerated = Effect.fn("writeGenerated")(function* (directory, name, files) {
|
|
9
|
+
const fs = yield* FileSystem.FileSystem;
|
|
10
|
+
const path = yield* Path.Path;
|
|
11
|
+
const output = path.resolve(directory, name);
|
|
12
|
+
yield* fs.makeDirectory(output, { recursive: true });
|
|
13
|
+
yield* Effect.forEach(Object.entries(files), ([file, contents]) => fs.writeFileString(path.join(output, file), contents), { discard: true });
|
|
14
|
+
const written = Object.keys(files).map((file) => `${output}/${file}`);
|
|
15
|
+
yield* Console.log(`Generated ${written.join(", ")}`);
|
|
16
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Option, Path } from "effect";
|
|
2
|
+
import { CliError, Command } from "effect/cli";
|
|
3
|
+
export declare const dependencies: readonly [];
|
|
4
|
+
export declare const standardSchema: Command.Command<"standard-schema", {
|
|
5
|
+
readonly input: URL;
|
|
6
|
+
readonly output: Option.Option<string>;
|
|
7
|
+
}, {}, CliError.UserError, import("effect/Crypto").Crypto | import("effect/Stdio").Stdio | (import("effect/FileSystem").FileSystem | import("effect/http/HttpClient").HttpClient | Path.Path)>;
|