sveltekit-openapi-remote 0.1.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/LICENSE +21 -0
- package/README.md +302 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +159 -0
- package/dist/cli.js.map +1 -0
- package/dist/generator.d.ts +23 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +252 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/index.d.ts +20 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +57 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tam
|
|
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
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# sveltekit-openapi-remote
|
|
2
|
+
|
|
3
|
+
Generate typed SvelteKit remote functions (`query`, `command`, `form`) directly from OpenAPI specs. Point it at your API spec and get ready-to-use server functions with full type safety.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
1. You provide an OpenAPI spec (URL, file path, or pre-generated `api.d.ts`)
|
|
8
|
+
2. The CLI generates TypeScript types via [openapi-typescript](https://github.com/openapi-ts/openapi-typescript)
|
|
9
|
+
3. It parses those types and generates SvelteKit remote function files
|
|
10
|
+
4. Your app imports these generated functions and uses them with full type safety
|
|
11
|
+
|
|
12
|
+
The generated functions use SvelteKit's `query()`, `command()`, and `form()` from `$app/server`, wired up to your API through [openapi-fetch](https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch).
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install sveltekit-openapi-remote
|
|
18
|
+
# or
|
|
19
|
+
pnpm add sveltekit-openapi-remote
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Peer dependencies
|
|
23
|
+
|
|
24
|
+
These are required in your SvelteKit project:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install openapi-fetch zod
|
|
28
|
+
# openapi-typescript is only needed if using --spec (optional)
|
|
29
|
+
npm install -D openapi-typescript
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
### 1. Set up your openapi-fetch client
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// src/lib/api/client.ts
|
|
38
|
+
import createClient from 'openapi-fetch';
|
|
39
|
+
|
|
40
|
+
export const client = createClient({
|
|
41
|
+
baseUrl: 'https://api.example.com',
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Initialize the remote handlers
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// src/lib/api/remote.ts
|
|
49
|
+
import { createRemoteHandlers } from 'sveltekit-openapi-remote';
|
|
50
|
+
import { client } from './client';
|
|
51
|
+
|
|
52
|
+
export const {
|
|
53
|
+
handleGetQuery,
|
|
54
|
+
handlePostCommand,
|
|
55
|
+
handlePatchCommand,
|
|
56
|
+
handlePutCommand,
|
|
57
|
+
handleDeleteCommand,
|
|
58
|
+
handlePostForm,
|
|
59
|
+
handlePatchForm,
|
|
60
|
+
handlePutForm,
|
|
61
|
+
handleDeleteForm,
|
|
62
|
+
} = createRemoteHandlers(client);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3. Generate remote functions
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# From an OpenAPI spec URL
|
|
69
|
+
npx sveltekit-openapi-remote generate \
|
|
70
|
+
--spec https://petstore3.swagger.io/api/v3/openapi.json \
|
|
71
|
+
--output src/lib/remote/generated \
|
|
72
|
+
--client '$lib/api/remote'
|
|
73
|
+
|
|
74
|
+
# From a local spec file (JSON or YAML)
|
|
75
|
+
npx sveltekit-openapi-remote generate \
|
|
76
|
+
--spec ./openapi.yaml \
|
|
77
|
+
--output src/lib/remote/generated \
|
|
78
|
+
--client '$lib/api/remote'
|
|
79
|
+
|
|
80
|
+
# From an existing api.d.ts (skip openapi-typescript step)
|
|
81
|
+
npx sveltekit-openapi-remote generate \
|
|
82
|
+
--types-path src/lib/types/api.d.ts \
|
|
83
|
+
--output src/lib/remote/generated \
|
|
84
|
+
--client '$lib/api/remote'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 4. Use in your SvelteKit app
|
|
88
|
+
|
|
89
|
+
```svelte
|
|
90
|
+
<!-- src/routes/pets/+page.svelte -->
|
|
91
|
+
<script>
|
|
92
|
+
import { getPetFindByStatus } from '$lib/remote/generated/pet.remote';
|
|
93
|
+
|
|
94
|
+
let pets = $derived(getPetFindByStatus({ query: { status: 'available' } }));
|
|
95
|
+
</script>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## CLI reference
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
npx sveltekit-openapi-remote generate [options]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Options
|
|
105
|
+
|
|
106
|
+
| Option | Required | Description |
|
|
107
|
+
|--------|----------|-------------|
|
|
108
|
+
| `--spec <path\|url>` | * | OpenAPI spec file or URL. Runs openapi-typescript to generate types. |
|
|
109
|
+
| `--types-path <path>` | * | Path to an existing `api.d.ts` file. Skips type generation. |
|
|
110
|
+
| `--output <dir>` | Yes | Output directory for generated files. |
|
|
111
|
+
| `--client <path>` | Yes | Import path to your initialized handlers file (e.g. `$lib/api/remote`). |
|
|
112
|
+
| `--grouping <mode>` | No | `"segment"` (default) or `"single"`. Controls file output. |
|
|
113
|
+
| `--depth <n>` | No | Segment depth for grouping (default: `1`). Only used with `--grouping segment`. |
|
|
114
|
+
| `--dry-run` | No | Preview what files would be generated without writing. |
|
|
115
|
+
| `--quiet` | No | Suppress all output except errors. Useful for CI. |
|
|
116
|
+
| `--help` | No | Show help text. |
|
|
117
|
+
|
|
118
|
+
\* Must provide either `--spec` or `--types-path`, not both.
|
|
119
|
+
|
|
120
|
+
### `--spec` vs `--types-path`
|
|
121
|
+
|
|
122
|
+
Use `--spec` when you want the CLI to handle everything — it runs `openapi-typescript` internally and writes `api.d.ts` to the output directory.
|
|
123
|
+
|
|
124
|
+
Use `--types-path` if you already generate your `api.d.ts` separately (e.g. as part of your build pipeline) and just want the remote function generation.
|
|
125
|
+
|
|
126
|
+
### `--grouping` and `--depth`
|
|
127
|
+
|
|
128
|
+
Controls how generated functions are split across files.
|
|
129
|
+
|
|
130
|
+
**`--grouping segment --depth 1`** (default) groups by the first URL segment:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
src/lib/remote/generated/
|
|
134
|
+
├── api.d.ts
|
|
135
|
+
├── pet.remote.ts # /pet, /pet/{petId}, /pet/findByStatus, ...
|
|
136
|
+
├── store.remote.ts # /store/inventory, /store/order, ...
|
|
137
|
+
└── user.remote.ts # /user, /user/{username}, /user/login, ...
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**`--grouping segment --depth 2`** groups by the first two non-parameter segments:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
src/lib/remote/generated/
|
|
144
|
+
├── api.d.ts
|
|
145
|
+
├── pet.remote.ts
|
|
146
|
+
├── pet-findByStatus.remote.ts
|
|
147
|
+
├── pet-findByTags.remote.ts
|
|
148
|
+
├── store-inventory.remote.ts
|
|
149
|
+
├── store-order.remote.ts
|
|
150
|
+
├── user.remote.ts
|
|
151
|
+
├── user-createWithList.remote.ts
|
|
152
|
+
├── user-login.remote.ts
|
|
153
|
+
└── user-logout.remote.ts
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**`--grouping single`** puts everything in one file:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
src/lib/remote/generated/
|
|
160
|
+
├── api.d.ts
|
|
161
|
+
└── api.remote.ts
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `--client`
|
|
165
|
+
|
|
166
|
+
The import path that generated files will use to import your handlers. This should match how your SvelteKit project resolves imports — typically a `$lib` alias:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
--client '$lib/api/remote'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The generated files will contain:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import {
|
|
176
|
+
handleGetQuery,
|
|
177
|
+
handlePostCommand,
|
|
178
|
+
// ...
|
|
179
|
+
} from '$lib/api/remote';
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## What gets generated
|
|
183
|
+
|
|
184
|
+
For each endpoint in your OpenAPI spec, the CLI generates typed SvelteKit remote functions:
|
|
185
|
+
|
|
186
|
+
| HTTP Method | Has Path Params | Generated Functions |
|
|
187
|
+
|-------------|----------------|---------------------|
|
|
188
|
+
| GET | any | `query()` |
|
|
189
|
+
| POST | no | `command()` + `form()` |
|
|
190
|
+
| POST | yes | `command()` + `form()` with `{ path, body }` |
|
|
191
|
+
| PATCH | no | `command()` + `form()` |
|
|
192
|
+
| PATCH | yes | `command()` + `form()` with `{ path, body }` |
|
|
193
|
+
| PUT | no | `command()` + `form()` |
|
|
194
|
+
| PUT | yes | `command()` + `form()` with `{ path, body }` |
|
|
195
|
+
| DELETE | any | `command()` + `form()` |
|
|
196
|
+
|
|
197
|
+
### Function naming
|
|
198
|
+
|
|
199
|
+
- HTTP method as prefix: `get`, `post`, `put`, `patch`, `delete`
|
|
200
|
+
- Path segments in camelCase: `/store/order` becomes `StoreOrder`
|
|
201
|
+
- Path parameters become `By{Param}`: `/pet/{petId}` becomes `PetByPetId`
|
|
202
|
+
- Mutations get `Command` and `Form` suffixes
|
|
203
|
+
|
|
204
|
+
**Examples:**
|
|
205
|
+
|
|
206
|
+
| Endpoint | Generated name |
|
|
207
|
+
|----------|---------------|
|
|
208
|
+
| `GET /pet/findByStatus` | `getPetFindByStatus` |
|
|
209
|
+
| `GET /pet/{petId}` | `getPetByPetId` |
|
|
210
|
+
| `POST /pet` | `postPetCommand`, `postPetForm` |
|
|
211
|
+
| `DELETE /store/order/{orderId}` | `deleteStoreOrderByOrderIdCommand`, `deleteStoreOrderByOrderIdForm` |
|
|
212
|
+
| `PUT /user/{username}` | `putUserByUsernameCommand`, `putUserByUsernameForm` |
|
|
213
|
+
|
|
214
|
+
### Example output
|
|
215
|
+
|
|
216
|
+
For the [Petstore API](https://petstore3.swagger.io/), the generated `store.remote.ts` looks like:
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { query, command, form } from '$app/server';
|
|
220
|
+
import { z } from 'zod';
|
|
221
|
+
import type { paths } from './api';
|
|
222
|
+
import { type GetParameters, type GetRequestBody } from 'sveltekit-openapi-remote';
|
|
223
|
+
import {
|
|
224
|
+
handleDeleteCommand,
|
|
225
|
+
handleDeleteForm,
|
|
226
|
+
handleGetQuery,
|
|
227
|
+
handlePostCommand,
|
|
228
|
+
handlePostForm,
|
|
229
|
+
} from '$lib/api/remote';
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Auto-generated remote functions
|
|
233
|
+
* DO NOT EDIT - Run 'npx sveltekit-openapi-remote generate' to regenerate
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
export const getStoreInventory = query(
|
|
237
|
+
z.custom<GetParameters<paths, '/store/inventory', 'get'>>(),
|
|
238
|
+
async (params) => handleGetQuery('/store/inventory', params)
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
export const postStoreOrderCommand = command(
|
|
242
|
+
z.custom<GetRequestBody<paths, '/store/order', 'post'>>(),
|
|
243
|
+
async (body) => handlePostCommand('/store/order', body)
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
export const postStoreOrderForm = form(
|
|
247
|
+
z.custom<GetRequestBody<paths, '/store/order', 'post'>>(),
|
|
248
|
+
async (body) => handlePostForm('/store/order', body)
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
export const getStoreOrderByOrderId = query(
|
|
252
|
+
z.custom<GetParameters<paths, '/store/order/{orderId}', 'get'>>(),
|
|
253
|
+
async (params) => handleGetQuery('/store/order/{orderId}', params)
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
export const deleteStoreOrderByOrderIdCommand = command(
|
|
257
|
+
z.custom<GetParameters<paths, '/store/order/{orderId}', 'delete'>>(),
|
|
258
|
+
async (params) => handleDeleteCommand('/store/order/{orderId}', params)
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
export const deleteStoreOrderByOrderIdForm = form(
|
|
262
|
+
z.custom<GetParameters<paths, '/store/order/{orderId}', 'delete'>>(),
|
|
263
|
+
async (params) => handleDeleteForm('/store/order/{orderId}', params)
|
|
264
|
+
);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Regeneration
|
|
268
|
+
|
|
269
|
+
Running the generator again will:
|
|
270
|
+
- Delete previously generated `.remote.ts` files (identified by the `DO NOT EDIT` header)
|
|
271
|
+
- Preserve any hand-written `.remote.ts` files you've added
|
|
272
|
+
- Write the new generated files
|
|
273
|
+
|
|
274
|
+
Add the generate command to your `package.json` scripts:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"scripts": {
|
|
279
|
+
"generate:api": "sveltekit-openapi-remote generate --spec https://api.example.com/openapi.json --output src/lib/remote/generated --client '$lib/api/remote'"
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Error handling
|
|
285
|
+
|
|
286
|
+
The runtime handlers throw SvelteKit errors automatically:
|
|
287
|
+
|
|
288
|
+
- **No response** (network failure) throws `error(503)`
|
|
289
|
+
- **API error response** throws `error(statusCode)` with the error message
|
|
290
|
+
- **No data returned** throws `error(404)`
|
|
291
|
+
|
|
292
|
+
## Requirements
|
|
293
|
+
|
|
294
|
+
- Node.js 20+
|
|
295
|
+
- SvelteKit 2.x
|
|
296
|
+
- openapi-typescript 7.x (only if using `--spec`)
|
|
297
|
+
- openapi-fetch
|
|
298
|
+
- zod 3.x
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
export interface CliArgs {
|
|
4
|
+
spec?: string;
|
|
5
|
+
typesPath?: string;
|
|
6
|
+
output: string;
|
|
7
|
+
client: string;
|
|
8
|
+
grouping: 'single' | 'segment';
|
|
9
|
+
depth: number;
|
|
10
|
+
dryRun: boolean;
|
|
11
|
+
quiet: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function createProgram(): Command;
|
|
14
|
+
export declare function validateArgs(opts: Record<string, any>): CliArgs;
|
|
15
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAS5C,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAaD,wBAAgB,aAAa,IAAI,OAAO,CAkCvC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAkB/D"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { extractPaths, generateRemoteFiles, writeRemoteFiles } from './generator.js';
|
|
10
|
+
function getVersion() {
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const pkgPath = path.resolve(__dirname, '..', 'package.json');
|
|
13
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
14
|
+
return pkg.version;
|
|
15
|
+
}
|
|
16
|
+
function getNpxCommand() {
|
|
17
|
+
return process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
18
|
+
}
|
|
19
|
+
export function createProgram() {
|
|
20
|
+
const program = new Command();
|
|
21
|
+
program
|
|
22
|
+
.name('sveltekit-openapi-remote')
|
|
23
|
+
.description('Generate typed SvelteKit remote functions from OpenAPI specs')
|
|
24
|
+
.version(getVersion());
|
|
25
|
+
program
|
|
26
|
+
.command('generate')
|
|
27
|
+
.description('Generate remote function files from an OpenAPI spec or api.d.ts')
|
|
28
|
+
.option('--spec <path|url>', 'OpenAPI spec file or URL (runs openapi-typescript)')
|
|
29
|
+
.option('--types-path <path>', 'path to existing api.d.ts (skips type generation)')
|
|
30
|
+
.requiredOption('--output <dir>', 'output directory for generated files')
|
|
31
|
+
.requiredOption('--client <path>', 'import path to your initialized handlers file')
|
|
32
|
+
.addOption(new Option('--grouping <mode>', 'file output mode')
|
|
33
|
+
.choices(['single', 'segment'])
|
|
34
|
+
.default('segment'))
|
|
35
|
+
.option('--depth <n>', 'segment depth for file grouping', '1')
|
|
36
|
+
.option('--dry-run', 'preview what files would be generated without writing', false)
|
|
37
|
+
.option('--quiet', 'suppress all output except errors', false)
|
|
38
|
+
.action(async (opts) => {
|
|
39
|
+
try {
|
|
40
|
+
const args = validateArgs(opts);
|
|
41
|
+
await runGenerate(args);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
console.error(chalk.red(`\nError: ${e.message}`));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return program;
|
|
49
|
+
}
|
|
50
|
+
export function validateArgs(opts) {
|
|
51
|
+
if (!opts.spec && !opts.typesPath) {
|
|
52
|
+
throw new Error('must provide either --spec or --types-path');
|
|
53
|
+
}
|
|
54
|
+
if (opts.spec && opts.typesPath) {
|
|
55
|
+
throw new Error('cannot provide both --spec and --types-path');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
spec: opts.spec,
|
|
59
|
+
typesPath: opts.typesPath,
|
|
60
|
+
output: opts.output,
|
|
61
|
+
client: opts.client,
|
|
62
|
+
grouping: opts.grouping,
|
|
63
|
+
depth: parseInt(opts.depth ?? '1', 10),
|
|
64
|
+
dryRun: opts.dryRun ?? false,
|
|
65
|
+
quiet: opts.quiet ?? false,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function createLogger(quiet) {
|
|
69
|
+
const noop = () => { };
|
|
70
|
+
return {
|
|
71
|
+
log: quiet ? noop : (...a) => console.log(...a),
|
|
72
|
+
spinner: (text) => quiet ? { start: () => ({ succeed: noop, fail: noop }) } : ora(text),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function runGenerate(args) {
|
|
76
|
+
const { log, spinner } = createLogger(args.quiet);
|
|
77
|
+
log();
|
|
78
|
+
log(chalk.bold('sveltekit-openapi-remote'));
|
|
79
|
+
log();
|
|
80
|
+
let typesPath = args.typesPath;
|
|
81
|
+
// Step 1: Generate types from spec if needed
|
|
82
|
+
if (args.spec) {
|
|
83
|
+
if (args.dryRun) {
|
|
84
|
+
log(` ${chalk.dim('•')} Would run openapi-typescript on ${chalk.cyan(args.spec)}`);
|
|
85
|
+
log(` ${chalk.dim('•')} Would write api.d.ts to ${chalk.cyan(args.output)}`);
|
|
86
|
+
log();
|
|
87
|
+
log(chalk.yellow('Dry run: --spec requires running openapi-typescript to proceed.'));
|
|
88
|
+
log(chalk.yellow('Use --types-path with an existing api.d.ts for a full dry run.'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const s = spinner(`Running openapi-typescript on ${chalk.cyan(args.spec)}`).start();
|
|
92
|
+
const outputTypesPath = path.join(args.output, 'api.d.ts');
|
|
93
|
+
if (!fs.existsSync(args.output)) {
|
|
94
|
+
fs.mkdirSync(args.output, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
execFileSync(getNpxCommand(), ['openapi-typescript', args.spec, '-o', outputTypesPath], {
|
|
98
|
+
stdio: 'pipe',
|
|
99
|
+
});
|
|
100
|
+
s.succeed(`Types generated ${chalk.dim(`→ ${outputTypesPath}`)}`);
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
s.fail('openapi-typescript failed');
|
|
104
|
+
const stderr = e?.stderr?.toString().trim();
|
|
105
|
+
const detail = stderr ? `\n${stderr}` : '';
|
|
106
|
+
throw new Error(`openapi-typescript failed. Is it installed? (npm install -D openapi-typescript)${detail}`);
|
|
107
|
+
}
|
|
108
|
+
typesPath = outputTypesPath;
|
|
109
|
+
}
|
|
110
|
+
// Step 2: Read types file
|
|
111
|
+
const s2 = spinner(`Reading types from ${chalk.cyan(typesPath)}`).start();
|
|
112
|
+
if (!fs.existsSync(typesPath)) {
|
|
113
|
+
s2.fail(`Types file not found: ${typesPath}`);
|
|
114
|
+
throw new Error(`Types file not found: ${typesPath}`);
|
|
115
|
+
}
|
|
116
|
+
const apiTypesContent = fs.readFileSync(typesPath, 'utf-8');
|
|
117
|
+
s2.succeed(`Types loaded from ${chalk.cyan(typesPath)}`);
|
|
118
|
+
// Step 3: Extract paths
|
|
119
|
+
const s3 = spinner('Extracting API paths').start();
|
|
120
|
+
const paths = extractPaths(apiTypesContent);
|
|
121
|
+
s3.succeed(`Found ${chalk.green(paths.length.toString())} API paths`);
|
|
122
|
+
// Step 4: Generate files
|
|
123
|
+
const s4 = spinner('Generating remote functions').start();
|
|
124
|
+
const files = generateRemoteFiles(paths, {
|
|
125
|
+
output: args.output,
|
|
126
|
+
clientImport: args.client,
|
|
127
|
+
grouping: args.grouping,
|
|
128
|
+
depth: args.depth,
|
|
129
|
+
});
|
|
130
|
+
s4.succeed(`Generated ${chalk.green(files.size.toString())} file(s)`);
|
|
131
|
+
// Step 5: Write files (or preview for dry run)
|
|
132
|
+
if (args.dryRun) {
|
|
133
|
+
log();
|
|
134
|
+
log(chalk.bold.yellow('Dry run') + ' — files that would be generated:');
|
|
135
|
+
log();
|
|
136
|
+
for (const filename of files.keys()) {
|
|
137
|
+
log(` ${chalk.dim('•')} ${path.join(args.output, filename)}`);
|
|
138
|
+
}
|
|
139
|
+
log();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const s5 = spinner(`Writing to ${chalk.cyan(args.output)}`).start();
|
|
143
|
+
writeRemoteFiles(files, args.output);
|
|
144
|
+
s5.succeed(`Written to ${chalk.cyan(args.output)}`);
|
|
145
|
+
// Summary
|
|
146
|
+
log();
|
|
147
|
+
log(`${chalk.bold.green('Done!')} Generated files:`);
|
|
148
|
+
log();
|
|
149
|
+
for (const filename of files.keys()) {
|
|
150
|
+
log(` ${chalk.dim('•')} ${filename}`);
|
|
151
|
+
}
|
|
152
|
+
log();
|
|
153
|
+
}
|
|
154
|
+
// Only run when executed directly (not when imported by tests)
|
|
155
|
+
const isMain = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
156
|
+
if (isMain) {
|
|
157
|
+
createProgram().parseAsync();
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface PathInfo {
|
|
2
|
+
path: string;
|
|
3
|
+
methods: {
|
|
4
|
+
method: 'get' | 'post' | 'patch' | 'put' | 'delete';
|
|
5
|
+
hasParams: boolean;
|
|
6
|
+
hasBody: boolean;
|
|
7
|
+
hasQuery: boolean;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
export interface GeneratorOptions {
|
|
11
|
+
output: string;
|
|
12
|
+
clientImport: string;
|
|
13
|
+
grouping: 'single' | 'segment';
|
|
14
|
+
depth: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function extractPaths(apiTypesContent: string): PathInfo[];
|
|
17
|
+
export declare function pathToFunctionName(pathStr: string, method: string, variant?: 'Command' | 'Form'): string;
|
|
18
|
+
export declare function pathToFilename(pathStr: string, depth: number): string;
|
|
19
|
+
/** Generate the content for a single .remote.ts file */
|
|
20
|
+
export declare function generateFileContent(paths: PathInfo[], clientImport: string): string;
|
|
21
|
+
export declare function generateRemoteFiles(paths: PathInfo[], options: GeneratorOptions): Map<string, string>;
|
|
22
|
+
export declare function writeRemoteFiles(files: Map<string, string>, outputDir: string): void;
|
|
23
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;QACpD,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACnB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAsCD,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,EAAE,CAiDhE;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,GAC3B,MAAM,CAyBR;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAcrE;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAmDnF;AAsCD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,gBAAgB,GACxB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAwCrB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1B,SAAS,EAAE,MAAM,GAChB,IAAI,CAmBN"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
function extractInterfaceBody(content, name) {
|
|
4
|
+
const startRegex = new RegExp(`export interface ${name}\\s*\\{`);
|
|
5
|
+
const startMatch = startRegex.exec(content);
|
|
6
|
+
if (!startMatch)
|
|
7
|
+
return null;
|
|
8
|
+
let depth = 1;
|
|
9
|
+
let pos = startMatch.index + startMatch[0].length;
|
|
10
|
+
while (pos < content.length && depth > 0) {
|
|
11
|
+
if (content[pos] === '{')
|
|
12
|
+
depth++;
|
|
13
|
+
else if (content[pos] === '}')
|
|
14
|
+
depth--;
|
|
15
|
+
pos++;
|
|
16
|
+
}
|
|
17
|
+
return content.slice(startMatch.index + startMatch[0].length, pos - 1);
|
|
18
|
+
}
|
|
19
|
+
function extractPathBlock(content, startIndex) {
|
|
20
|
+
// Find the colon after the key, then the opening brace after it
|
|
21
|
+
const colonPos = content.indexOf(':', startIndex);
|
|
22
|
+
if (colonPos === -1)
|
|
23
|
+
return null;
|
|
24
|
+
let pos = content.indexOf('{', colonPos);
|
|
25
|
+
if (pos === -1)
|
|
26
|
+
return null;
|
|
27
|
+
let depth = 1;
|
|
28
|
+
pos++;
|
|
29
|
+
while (pos < content.length && depth > 0) {
|
|
30
|
+
if (content[pos] === '{')
|
|
31
|
+
depth++;
|
|
32
|
+
else if (content[pos] === '}')
|
|
33
|
+
depth--;
|
|
34
|
+
pos++;
|
|
35
|
+
}
|
|
36
|
+
return content.slice(startIndex, pos);
|
|
37
|
+
}
|
|
38
|
+
export function extractPaths(apiTypesContent) {
|
|
39
|
+
const pathsContent = extractInterfaceBody(apiTypesContent, 'paths');
|
|
40
|
+
if (!pathsContent) {
|
|
41
|
+
throw new Error('Could not find paths interface in api.d.ts');
|
|
42
|
+
}
|
|
43
|
+
const pathKeyRegex = /"(\/[^"]*)":\s*\{/g;
|
|
44
|
+
const paths = [];
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = pathKeyRegex.exec(pathsContent)) !== null) {
|
|
47
|
+
const pathStr = match[1];
|
|
48
|
+
const pathBlock = extractPathBlock(pathsContent, match.index);
|
|
49
|
+
if (!pathBlock)
|
|
50
|
+
continue;
|
|
51
|
+
// Advance past this block to avoid matching nested keys
|
|
52
|
+
pathKeyRegex.lastIndex = match.index + pathBlock.length;
|
|
53
|
+
const methods = [];
|
|
54
|
+
const methodChecks = [
|
|
55
|
+
{ method: 'get', regex: /\bget:\s*(?:operations\[|\{)/ },
|
|
56
|
+
{ method: 'post', regex: /\bpost:\s*(?:operations\[|\{)/ },
|
|
57
|
+
{ method: 'patch', regex: /\bpatch:\s*(?:operations\[|\{)/ },
|
|
58
|
+
{ method: 'put', regex: /\bput:\s*(?:operations\[|\{)/ },
|
|
59
|
+
{ method: 'delete', regex: /\bdelete:\s*(?:operations\[|\{)/ },
|
|
60
|
+
];
|
|
61
|
+
for (const { method, regex } of methodChecks) {
|
|
62
|
+
if (regex.test(pathBlock)) {
|
|
63
|
+
const hasParams = pathStr.includes('{');
|
|
64
|
+
const hasBody = method !== 'get' && method !== 'delete';
|
|
65
|
+
const hasQuery = method === 'get';
|
|
66
|
+
methods.push({ method, hasParams, hasBody, hasQuery });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (methods.length > 0) {
|
|
70
|
+
paths.push({ path: pathStr, methods });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (paths.length === 0 && pathsContent.trim().length > 0) {
|
|
74
|
+
console.warn('Warning: paths interface found but no HTTP methods detected. ' +
|
|
75
|
+
'The api.d.ts format may be unsupported.');
|
|
76
|
+
}
|
|
77
|
+
return paths;
|
|
78
|
+
}
|
|
79
|
+
export function pathToFunctionName(pathStr, method, variant) {
|
|
80
|
+
const segments = pathStr.replace(/^\//, '').split('/');
|
|
81
|
+
const parts = segments.map((segment, index) => {
|
|
82
|
+
if (segment.startsWith('{') && segment.endsWith('}')) {
|
|
83
|
+
const param = segment.slice(1, -1);
|
|
84
|
+
return 'By' + param.charAt(0).toUpperCase() + param.slice(1);
|
|
85
|
+
}
|
|
86
|
+
const words = segment.split('-');
|
|
87
|
+
return words
|
|
88
|
+
.map((word, i) => {
|
|
89
|
+
if (index === 0 && i === 0) {
|
|
90
|
+
return word;
|
|
91
|
+
}
|
|
92
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
93
|
+
})
|
|
94
|
+
.join('');
|
|
95
|
+
});
|
|
96
|
+
const baseName = parts.join('');
|
|
97
|
+
const functionName = method.toLowerCase() + baseName.charAt(0).toUpperCase() + baseName.slice(1);
|
|
98
|
+
return variant ? functionName + variant : functionName;
|
|
99
|
+
}
|
|
100
|
+
export function pathToFilename(pathStr, depth) {
|
|
101
|
+
const segments = pathStr
|
|
102
|
+
.replace(/^\//, '')
|
|
103
|
+
.split('/')
|
|
104
|
+
.filter(s => !s.startsWith('{'));
|
|
105
|
+
if (segments.length === 0) {
|
|
106
|
+
return 'root.remote.ts';
|
|
107
|
+
}
|
|
108
|
+
const groupSegments = segments.slice(0, depth);
|
|
109
|
+
const fileBase = groupSegments.join('-').replace(/[^a-zA-Z0-9-]/g, '-');
|
|
110
|
+
return `${fileBase}.remote.ts`;
|
|
111
|
+
}
|
|
112
|
+
/** Generate the content for a single .remote.ts file */
|
|
113
|
+
export function generateFileContent(paths, clientImport) {
|
|
114
|
+
const allHandlers = new Set();
|
|
115
|
+
const allTypes = new Set();
|
|
116
|
+
for (const pathInfo of paths) {
|
|
117
|
+
for (const methodInfo of pathInfo.methods) {
|
|
118
|
+
const m = methodInfo.method;
|
|
119
|
+
if (m === 'get') {
|
|
120
|
+
allHandlers.add('handleGetQuery');
|
|
121
|
+
allTypes.add('GetParameters');
|
|
122
|
+
}
|
|
123
|
+
else if (m === 'delete') {
|
|
124
|
+
allHandlers.add('handleDeleteCommand');
|
|
125
|
+
allHandlers.add('handleDeleteForm');
|
|
126
|
+
allTypes.add('GetParameters');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const Method = m.charAt(0).toUpperCase() + m.slice(1);
|
|
130
|
+
allHandlers.add(`handle${Method}Command`);
|
|
131
|
+
allHandlers.add(`handle${Method}Form`);
|
|
132
|
+
if (methodInfo.hasParams)
|
|
133
|
+
allTypes.add('GetParameters');
|
|
134
|
+
allTypes.add('GetRequestBody');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const handlerImports = Array.from(allHandlers).sort().join(',\n ');
|
|
139
|
+
const typeImportList = Array.from(allTypes).sort();
|
|
140
|
+
const typeImportLine = typeImportList.length > 0
|
|
141
|
+
? `import { type ${typeImportList.join(', type ')} } from 'sveltekit-openapi-remote';\n`
|
|
142
|
+
: '';
|
|
143
|
+
const imports = `import { query, command, form } from '$app/server';
|
|
144
|
+
import { z } from 'zod';
|
|
145
|
+
import type { paths } from './api';
|
|
146
|
+
${typeImportLine}import {
|
|
147
|
+
${handlerImports},
|
|
148
|
+
} from '${clientImport}';
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Auto-generated remote functions
|
|
152
|
+
* DO NOT EDIT - Run 'npx sveltekit-openapi-remote generate' to regenerate
|
|
153
|
+
*/
|
|
154
|
+
`;
|
|
155
|
+
const functions = [];
|
|
156
|
+
for (const pathInfo of paths) {
|
|
157
|
+
for (const methodInfo of pathInfo.methods) {
|
|
158
|
+
functions.push(...generateFunctionCode(pathInfo.path, methodInfo.method, methodInfo));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return imports + '\n' + functions.join('\n\n') + '\n';
|
|
162
|
+
}
|
|
163
|
+
function generateFunctionCode(pathStr, method, info) {
|
|
164
|
+
const codes = [];
|
|
165
|
+
if (method === 'get') {
|
|
166
|
+
const funcName = pathToFunctionName(pathStr, method);
|
|
167
|
+
codes.push(`export const ${funcName} = query(\n\tz.custom<GetParameters<paths, '${pathStr}', 'get'>>(),\n\tasync (params) => handleGetQuery('${pathStr}', params)\n);`);
|
|
168
|
+
}
|
|
169
|
+
else if (method === 'delete') {
|
|
170
|
+
const commandName = pathToFunctionName(pathStr, method, 'Command');
|
|
171
|
+
const formName = pathToFunctionName(pathStr, method, 'Form');
|
|
172
|
+
codes.push(`export const ${commandName} = command(\n\tz.custom<GetParameters<paths, '${pathStr}', 'delete'>>(),\n\tasync (params) => handleDeleteCommand('${pathStr}', params)\n);`);
|
|
173
|
+
codes.push(`export const ${formName} = form(\n\tz.custom<GetParameters<paths, '${pathStr}', 'delete'>>(),\n\tasync (params) => handleDeleteForm('${pathStr}', params)\n);`);
|
|
174
|
+
}
|
|
175
|
+
else if (info.hasParams) {
|
|
176
|
+
const commandName = pathToFunctionName(pathStr, method, 'Command');
|
|
177
|
+
const formName = pathToFunctionName(pathStr, method, 'Form');
|
|
178
|
+
const Method = method.charAt(0).toUpperCase() + method.slice(1);
|
|
179
|
+
const commandHandler = `handle${Method}Command`;
|
|
180
|
+
const formHandler = `handle${Method}Form`;
|
|
181
|
+
codes.push(`export const ${commandName} = command(\n\tz.object({\n\t\tpath: z.custom<GetParameters<paths, '${pathStr}', '${method}'>['path']>(),\n\t\tbody: z.custom<GetRequestBody<paths, '${pathStr}', '${method}'>>()\n\t}),\n\tasync (input) => ${commandHandler}('${pathStr}', input)\n);`);
|
|
182
|
+
codes.push(`export const ${formName} = form(\n\tz.object({\n\t\tpath: z.custom<GetParameters<paths, '${pathStr}', '${method}'>['path']>(),\n\t\tbody: z.custom<GetRequestBody<paths, '${pathStr}', '${method}'>>()\n\t}),\n\tasync (input) => ${formHandler}('${pathStr}', input)\n);`);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
const commandName = pathToFunctionName(pathStr, method, 'Command');
|
|
186
|
+
const formName = pathToFunctionName(pathStr, method, 'Form');
|
|
187
|
+
const Method = method.charAt(0).toUpperCase() + method.slice(1);
|
|
188
|
+
const commandHandler = `handle${Method}Command`;
|
|
189
|
+
const formHandler = `handle${Method}Form`;
|
|
190
|
+
codes.push(`export const ${commandName} = command(\n\tz.custom<GetRequestBody<paths, '${pathStr}', '${method}'>>(),\n\tasync (body) => ${commandHandler}('${pathStr}', body)\n);`);
|
|
191
|
+
codes.push(`export const ${formName} = form(\n\tz.custom<GetRequestBody<paths, '${pathStr}', '${method}'>>(),\n\tasync (body) => ${formHandler}('${pathStr}', body)\n);`);
|
|
192
|
+
}
|
|
193
|
+
return codes;
|
|
194
|
+
}
|
|
195
|
+
export function generateRemoteFiles(paths, options) {
|
|
196
|
+
const nameMap = new Map();
|
|
197
|
+
for (const pathInfo of paths) {
|
|
198
|
+
for (const methodInfo of pathInfo.methods) {
|
|
199
|
+
const variants = methodInfo.method === 'get'
|
|
200
|
+
? [pathToFunctionName(pathInfo.path, methodInfo.method)]
|
|
201
|
+
: [
|
|
202
|
+
pathToFunctionName(pathInfo.path, methodInfo.method, 'Command'),
|
|
203
|
+
pathToFunctionName(pathInfo.path, methodInfo.method, 'Form'),
|
|
204
|
+
];
|
|
205
|
+
for (const name of variants) {
|
|
206
|
+
if (nameMap.has(name)) {
|
|
207
|
+
throw new Error(`Function name collision: "${name}" is generated by both "${nameMap.get(name)}" and "${pathInfo.path}" (${methodInfo.method})`);
|
|
208
|
+
}
|
|
209
|
+
nameMap.set(name, `${pathInfo.path} (${methodInfo.method})`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const fileMap = new Map();
|
|
214
|
+
if (options.grouping === 'single') {
|
|
215
|
+
fileMap.set('api.remote.ts', paths);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
for (const pathInfo of paths) {
|
|
219
|
+
const filename = pathToFilename(pathInfo.path, options.depth);
|
|
220
|
+
if (!fileMap.has(filename)) {
|
|
221
|
+
fileMap.set(filename, []);
|
|
222
|
+
}
|
|
223
|
+
fileMap.get(filename).push(pathInfo);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const result = new Map();
|
|
227
|
+
for (const [filename, filePaths] of fileMap.entries()) {
|
|
228
|
+
result.set(filename, generateFileContent(filePaths, options.clientImport));
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
export function writeRemoteFiles(files, outputDir) {
|
|
233
|
+
if (!fs.existsSync(outputDir)) {
|
|
234
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
const existingFiles = fs.readdirSync(outputDir);
|
|
238
|
+
for (const file of existingFiles) {
|
|
239
|
+
if (file.endsWith('.remote.ts')) {
|
|
240
|
+
const filePath = path.join(outputDir, file);
|
|
241
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
242
|
+
if (content.includes('DO NOT EDIT')) {
|
|
243
|
+
fs.unlinkSync(filePath);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
for (const [filename, content] of files.entries()) {
|
|
249
|
+
fs.writeFileSync(path.join(outputDir, filename), content, 'utf-8');
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface OpenapiClient {
|
|
2
|
+
GET: (path: string, options?: any) => Promise<any>;
|
|
3
|
+
POST: (path: string, options?: any) => Promise<any>;
|
|
4
|
+
PATCH: (path: string, options?: any) => Promise<any>;
|
|
5
|
+
PUT: (path: string, options?: any) => Promise<any>;
|
|
6
|
+
DELETE: (path: string, options?: any) => Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createRemoteHandlers(client: OpenapiClient): {
|
|
9
|
+
handleGetQuery: (path: string, params: any) => Promise<any>;
|
|
10
|
+
handlePostCommand: (path: string, body: any) => Promise<any>;
|
|
11
|
+
handlePatchCommand: (path: string, input: any) => Promise<any>;
|
|
12
|
+
handlePutCommand: (path: string, input: any) => Promise<any>;
|
|
13
|
+
handleDeleteCommand: (path: string, params: any) => Promise<any>;
|
|
14
|
+
handlePostForm: (path: string, body: any) => Promise<any>;
|
|
15
|
+
handlePatchForm: (path: string, input: any) => Promise<any>;
|
|
16
|
+
handlePutForm: (path: string, input: any) => Promise<any>;
|
|
17
|
+
handleDeleteForm: (path: string, params: any) => Promise<any>;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACpD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACrD,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACvD;AAkBD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa;2BACpB,MAAM,UAAU,GAAG;8BAKhB,MAAM,QAAQ,GAAG;+BAKhB,MAAM,SAAS,GAAG;6BAUpB,MAAM,SAAS,GAAG;gCAUf,MAAM,UAAU,GAAG;2BAzBrB,MAAM,QAAQ,GAAG;4BAKhB,MAAM,SAAS,GAAG;0BAUpB,MAAM,SAAS,GAAG;6BAUf,MAAM,UAAU,GAAG;EAgB7D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { error as svelteError } from '@sveltejs/kit';
|
|
2
|
+
function handleResponse(response, error, data) {
|
|
3
|
+
if (!response) {
|
|
4
|
+
throw svelteError(503, 'Network error: no response from service');
|
|
5
|
+
}
|
|
6
|
+
if (error) {
|
|
7
|
+
throw svelteError(error.statusCode ?? 500, error.message ?? 'An error occurred');
|
|
8
|
+
}
|
|
9
|
+
if (!data) {
|
|
10
|
+
throw svelteError(404, 'Not found');
|
|
11
|
+
}
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
export function createRemoteHandlers(client) {
|
|
15
|
+
async function handleGetQuery(path, params) {
|
|
16
|
+
const { data, error, response } = await client.GET(path, { params });
|
|
17
|
+
return handleResponse(response, error, data);
|
|
18
|
+
}
|
|
19
|
+
async function handlePostCommand(path, body) {
|
|
20
|
+
const { data, error, response } = await client.POST(path, { body });
|
|
21
|
+
return handleResponse(response, error, data);
|
|
22
|
+
}
|
|
23
|
+
async function handlePatchCommand(path, input) {
|
|
24
|
+
const hasPath = input && typeof input === 'object' && 'path' in input;
|
|
25
|
+
const hasBody = input && typeof input === 'object' && 'body' in input;
|
|
26
|
+
const { data, error, response } = await client.PATCH(path, {
|
|
27
|
+
...(hasPath && { params: { path: input.path } }),
|
|
28
|
+
...(hasBody && { body: input.body }),
|
|
29
|
+
});
|
|
30
|
+
return handleResponse(response, error, data);
|
|
31
|
+
}
|
|
32
|
+
async function handlePutCommand(path, input) {
|
|
33
|
+
const hasPath = input && typeof input === 'object' && 'path' in input;
|
|
34
|
+
const hasBody = input && typeof input === 'object' && 'body' in input;
|
|
35
|
+
const { data, error, response } = await client.PUT(path, {
|
|
36
|
+
...(hasPath && { params: { path: input.path } }),
|
|
37
|
+
...(hasBody && { body: input.body }),
|
|
38
|
+
});
|
|
39
|
+
return handleResponse(response, error, data);
|
|
40
|
+
}
|
|
41
|
+
async function handleDeleteCommand(path, params) {
|
|
42
|
+
const { data, error, response } = await client.DELETE(path, { params });
|
|
43
|
+
return handleResponse(response, error, data);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
handleGetQuery,
|
|
47
|
+
handlePostCommand,
|
|
48
|
+
handlePatchCommand,
|
|
49
|
+
handlePutCommand,
|
|
50
|
+
handleDeleteCommand,
|
|
51
|
+
handlePostForm: handlePostCommand,
|
|
52
|
+
handlePatchForm: handlePatchCommand,
|
|
53
|
+
handlePutForm: handlePutCommand,
|
|
54
|
+
handleDeleteForm: handleDeleteCommand,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Filter paths that support a given HTTP method */
|
|
2
|
+
export type PathsWithMethod<Paths, TMethod extends 'get' | 'post' | 'patch' | 'put' | 'delete'> = {
|
|
3
|
+
[P in keyof Paths]: TMethod extends keyof Paths[P] ? P : never;
|
|
4
|
+
}[keyof Paths];
|
|
5
|
+
/** Extract parameters (path + query) for a given path and method */
|
|
6
|
+
export type GetParameters<Paths, TPath extends keyof Paths, TMethod extends keyof Paths[TPath]> = Paths[TPath][TMethod] extends {
|
|
7
|
+
parameters: infer P;
|
|
8
|
+
} ? P : never;
|
|
9
|
+
/** Extract JSON request body for a given path and method */
|
|
10
|
+
export type GetRequestBody<Paths, TPath extends keyof Paths, TMethod extends keyof Paths[TPath]> = Paths[TPath][TMethod] extends {
|
|
11
|
+
requestBody: {
|
|
12
|
+
content: {
|
|
13
|
+
'application/json': infer B;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
} ? B : never;
|
|
17
|
+
/** Extract JSON response body (checks 200, then 201, falls back to unknown) */
|
|
18
|
+
export type GetResponse<Paths, TPath extends keyof Paths, TMethod extends keyof Paths[TPath]> = Paths[TPath][TMethod] extends {
|
|
19
|
+
responses: {
|
|
20
|
+
200: {
|
|
21
|
+
content: {
|
|
22
|
+
'application/json': infer R;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
} ? R : Paths[TPath][TMethod] extends {
|
|
27
|
+
responses: {
|
|
28
|
+
201: {
|
|
29
|
+
content: {
|
|
30
|
+
'application/json': infer R;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
} ? R : unknown;
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,MAAM,eAAe,CACzB,KAAK,EACL,OAAO,SAAS,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,IACzD;KACD,CAAC,IAAI,MAAM,KAAK,GAAG,OAAO,SAAS,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAC/D,CAAC,MAAM,KAAK,CAAC,CAAC;AAEf,oEAAoE;AACpE,MAAM,MAAM,aAAa,CACvB,KAAK,EACL,KAAK,SAAS,MAAM,KAAK,EACzB,OAAO,SAAS,MAAM,KAAK,CAAC,KAAK,CAAC,IAChC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAEtE,4DAA4D;AAC5D,MAAM,MAAM,cAAc,CACxB,KAAK,EACL,KAAK,SAAS,MAAM,KAAK,EACzB,OAAO,SAAS,MAAM,KAAK,CAAC,KAAK,CAAC,IAChC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS;IAChC,WAAW,EAAE;QAAE,OAAO,EAAE;YAAE,kBAAkB,EAAE,MAAM,CAAC,CAAA;SAAE,CAAA;KAAE,CAAC;CAC3D,GACG,CAAC,GACD,KAAK,CAAC;AAEV,+EAA+E;AAC/E,MAAM,MAAM,WAAW,CACrB,KAAK,EACL,KAAK,SAAS,MAAM,KAAK,EACzB,OAAO,SAAS,MAAM,KAAK,CAAC,KAAK,CAAC,IAChC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS;IAChC,SAAS,EAAE;QAAE,GAAG,EAAE;YAAE,OAAO,EAAE;gBAAE,kBAAkB,EAAE,MAAM,CAAC,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CAClE,GACG,CAAC,GACD,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS;IAC1B,SAAS,EAAE;QAAE,GAAG,EAAE;YAAE,OAAO,EAAE;gBAAE,kBAAkB,EAAE,MAAM,CAAC,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CAClE,GACD,CAAC,GACD,OAAO,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sveltekit-openapi-remote",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Generate SvelteKit remote functions directly from OpenAPI/Swagger specs.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Tam",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/tam2/sveltekit-openapi-remote.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/tam2/sveltekit-openapi-remote#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/tam2/sveltekit-openapi-remote/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"sveltekit",
|
|
18
|
+
"openapi",
|
|
19
|
+
"swagger",
|
|
20
|
+
"remote-functions",
|
|
21
|
+
"codegen",
|
|
22
|
+
"typescript",
|
|
23
|
+
"openapi-fetch",
|
|
24
|
+
"query",
|
|
25
|
+
"command",
|
|
26
|
+
"form"
|
|
27
|
+
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"sveltekit-openapi-remote": "./dist/cli.js"
|
|
30
|
+
},
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./runtime": {
|
|
38
|
+
"types": "./dist/runtime/index.d.ts",
|
|
39
|
+
"import": "./dist/runtime/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./types": {
|
|
42
|
+
"types": "./dist/types.d.ts",
|
|
43
|
+
"import": "./dist/types.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsc",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"test:watch": "vitest",
|
|
53
|
+
"prepublishOnly": "pnpm run build && pnpm test"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@sveltejs/kit": "^2.0.0",
|
|
57
|
+
"openapi-fetch": "^0.13.0",
|
|
58
|
+
"openapi-typescript": "^7.0.0",
|
|
59
|
+
"zod": "^3.0.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"openapi-typescript": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "^25.5.0",
|
|
68
|
+
"openapi-typescript": "^7.13.0",
|
|
69
|
+
"typescript": "^6.0.2",
|
|
70
|
+
"vitest": "^4.1.1"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"chalk": "^5.6.2",
|
|
74
|
+
"commander": "^14.0.3",
|
|
75
|
+
"ora": "^9.3.0"
|
|
76
|
+
}
|
|
77
|
+
}
|