arri 0.12.0 → 0.12.4

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 CHANGED
@@ -1,6 +1,42 @@
1
1
  # Arri RPC
2
2
 
3
- ## Installation
3
+ Typescript implementation of Arri RPC. It's built on top of [H3](https://github.com/unjs/h3) and uses [esbuild](https://esbuild.github.io/) for bundling.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quickstart](#quickstart)
8
+ - [Manual Setup](#manual-setup)
9
+ - [Install Dependencies](#install-dependencies)
10
+ - [Scaffold Your Project](#scaffold-your-project)
11
+ - [Usage](#usage)
12
+ - [File-Based Routing](#file-based-routing)
13
+ - [Manual Routing](#manual-routing)
14
+ - [Adding Non-RPC Routes](#adding-non-rpc-routes)
15
+ - [Adding Middleware](#adding-middleware)
16
+ - [Key Concepts](#key-concepts)
17
+ - [Arri Definition File](#arri-definition-file)
18
+ - [How Procedures Map To Endpoints](#how-procedures-map-to-endpoints)
19
+ - [Arri CLI](#arri-cli)
20
+
21
+ ## Quickstart
22
+
23
+ ```bash
24
+ # npm
25
+ npx arri init [project-name]
26
+ cd [project-name]
27
+ npm install
28
+ npm run dev
29
+
30
+ # pnpm
31
+ pnpm dlx arri init [project-name]
32
+ cd [project-name]
33
+ pnpm install
34
+ pnpm run dev
35
+ ```
36
+
37
+ ## Manual Setup
38
+
39
+ ### Install Dependencies
4
40
 
5
41
  ```bash
6
42
  # npm
@@ -10,7 +46,32 @@ npm install arri arri-validate
10
46
  pnpm install arri arri-validate
11
47
  ```
12
48
 
13
- ## Basic Setup Example
49
+ ### Scaffold Your Project
50
+
51
+ A basic Arri app directory looks something like this:
52
+
53
+ ```fs
54
+ |-- project-dir
55
+ |-- .arri // temp files go here
56
+ |-- .output // final bundle goes here
57
+ |-- src
58
+ |-- procedures // .rpc.ts files go here
59
+ |-- app.ts
60
+ |-- arri.config.ts
61
+ |-- package.json
62
+ |-- tsconfig.json
63
+ |
64
+ ```
65
+
66
+ Both `.arri` and `.output` should be added to your `.gitignore` file
67
+
68
+ ```txt
69
+ .arri
70
+ .output
71
+ node_modules
72
+ ```
73
+
74
+ #### Configuration File
14
75
 
15
76
  Create an `arri.config.ts` in the project directory
16
77
 
@@ -37,7 +98,9 @@ export default defineConfig({
37
98
  });
38
99
  ```
39
100
 
40
- Create an `app.ts` file in the source directory
101
+ ##### App Entry
102
+
103
+ Create an app entry file in your src directory. The name of the file must match whatever you put as the `entry` in your `arri.config.ts`.
41
104
 
42
105
  ```ts
43
106
  // ./src/app.ts
@@ -63,24 +126,30 @@ app.rpc("sayHello", {
63
126
  export default app;
64
127
  ```
65
128
 
129
+ ##### Package.json
130
+
66
131
  Setup your npm scripts:
67
132
 
68
133
  ```json
69
134
  {
135
+ "name": "my-arri-app",
136
+ "type": "module",
70
137
  "scripts": {
71
138
  "dev": "arri dev",
72
139
  "build": "arri build"
140
+ },
141
+ "dependencies": {
142
+ ...
143
+ },
144
+ "devDependencies": {
145
+ ...
73
146
  }
74
147
  }
75
148
  ```
76
149
 
77
- Start the dev server:
78
-
79
- ```bash
80
- npm run dev
81
- ```
150
+ ## Usage
82
151
 
83
- ## File Based Routing
152
+ ### File Based Routing
84
153
 
85
154
  Arri RPC comes with an optional file based router that will automatically register functions in the `./procedures` directory that end with the `.rpc.ts` file extension.
86
155
 
@@ -115,7 +184,7 @@ export default defineRpc({
115
184
  });
116
185
  ```
117
186
 
118
- ### Customizing the File Based Router
187
+ #### Customizing the File Based Router
119
188
 
120
189
  ```ts
121
190
  export default defineConfig({
@@ -125,9 +194,27 @@ export default defineConfig({
125
194
  });
126
195
  ```
127
196
 
128
- ## Adding Non-RPC Endpoints
197
+ ### Manual Routing
198
+
199
+ ```ts
200
+ // using the app instance
201
+ const app = new ArriApp()
202
+ app.rpc('sayHello', {...})
203
+
204
+ // using a sub-router
205
+ const app = new ArriApp();
206
+ const router = new ArriRoute();
207
+ router.rpc('sayHello', {...})
208
+ app.use(router)
209
+ ```
210
+
211
+ ### Adding Non-RPC Routes
212
+
213
+ You can also add generic endpoints for instances when a message-based RPC endpoint doesn't fit.
129
214
 
130
215
  ```ts
216
+ // using the app instance
217
+ const app = new ArriApp();
131
218
  app.route({
132
219
  method: "get",
133
220
  path: "/hello-world",
@@ -135,25 +222,192 @@ app.route({
135
222
  return "hello world";
136
223
  },
137
224
  });
225
+
226
+ // using a sub-router
227
+ const app = new ArriApp();
228
+ const router = new ArriRouter();
229
+ router.route({
230
+ method: "get",
231
+ path: "/hello-world",
232
+ handler(event) {
233
+ return "hello world",
234
+ }
235
+ })
236
+ app.use(router)
138
237
  ```
139
238
 
140
- ## Creating sub routers
239
+ ### Adding Middleware
141
240
 
142
241
  ```ts
143
- import { ArriApp, ArriRouter } from "arri";
144
-
145
242
  const app = new ArriApp();
146
- const router = new ArriRouter();
147
243
 
148
- router.rpc({
149
- // rpc config
244
+ const requestLoggerMiddleware = defineMiddleware((event) => {
245
+ console.log(`new request at ${event.path}`);
150
246
  });
151
247
 
152
- router.route({
153
- // route config
248
+ app.use(requestLoggerMiddleware);
249
+ ```
250
+
251
+ #### Adding to the RPC Context
252
+
253
+ Any values added to `event.context` will become available in the rpc instance
254
+
255
+ ```ts
256
+ const authMiddleware = defineMiddleware(async (event) => {
257
+ // assume you did something to get the user from the request
258
+ event.context.user = {
259
+ id: 1,
260
+ name: "John Doe",
261
+ email: "johndoe@gmail.com",
262
+ };
263
+ });
264
+
265
+ app.rpc("sayHello", {
266
+ params: undefined,
267
+ response: a.object({
268
+ message: a.string(),
269
+ }),
270
+ // user is available here
271
+ handler({ user }) {
272
+ return {
273
+ message: `Hello ${user.name}`,
274
+ };
275
+ },
154
276
  });
277
+ ```
278
+
279
+ To get type safety for these new properties create a `.d.ts` file and augment the `EventContext` provided by `H3`
280
+
281
+ ```ts
282
+ import "h3";
283
+
284
+ declare module "h3" {
285
+ interface H3EventContext {
286
+ user?: {
287
+ id: number;
288
+ name: string;
289
+ email: string;
290
+ };
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Adding Client Generators
296
+
297
+ Right now Arri RPC has client generators for the following languages:
298
+
299
+ - typescript
300
+ - dart
301
+
302
+ ```ts
303
+ // arri.config.ts
304
+ import { defineConfig } from "arri";
305
+ import { typescriptClientGenerator, dartClientGenerator } from "arri/dist/codegen";
306
+
307
+ export default defineConfig({
308
+ // rest of config
309
+ clientGenerators: [
310
+ typescriptClientGenerator({...}),
311
+ dartClientGenerator({...})
312
+ ]
313
+ });
314
+ ```
315
+
316
+ ## Key Concepts
317
+
318
+ ### Arri Definition File
319
+
320
+ The server generates a `__definition.json` file that acts as a schema for all of the procedures and models in the API. By default this schema is viewable from `/__definition` when the server is running, but it can be modified. The endpoint is also relative to the `rpcRoutePrefix` option.
321
+
322
+ It looks something like this:
323
+
324
+ ```json
325
+ {
326
+ "procedures": {
327
+ "sayHello": {
328
+ "path": "/say-hello",
329
+ "method": "post",
330
+ "params": "SayHelloParams",
331
+ "response": "SayHelloResponse"
332
+ }
333
+ // rest of procedures
334
+ },
335
+ "models": {
336
+ "SayHelloParams": {
337
+ "properties": {
338
+ "name": {
339
+ "type": "string"
340
+ }
341
+ }
342
+ },
343
+ "SayHelloResponse": {
344
+ "properties": {
345
+ "message": {
346
+ "type": "string"
347
+ }
348
+ }
349
+ }
350
+ // rest of models
351
+ }
352
+ }
353
+ ```
354
+
355
+ Arri is able to use this schema file to automatically generate clients in multiple languages. In this way it works similarly to an Open API schema, but with much better code-generation support. I've made a lot of deliberate choices in designing this schema to make code-generation easier and more consistent across languages. For example, Arri schemas use a superset of [JSON Type Definition](https://jsontypedef.com/) for their models instead of JSON Schema.
356
+
357
+ ### How Procedures Map To Endpoints
358
+
359
+ Every procedure maps to a different url based on it's name. For example given the following file structure:
360
+
361
+ ```fs
362
+ |--src
363
+ |--procedures
364
+ |--getStatus.rpc.ts
365
+ |--users
366
+ |--getUser.rpc.ts
367
+ |--updateUser.rpc.ts
368
+ ```
369
+
370
+ We will get the following endpoints:
371
+
372
+ ```txt
373
+ POST /get-status
374
+ POST /users/get-user
375
+ POST /users/update-user
376
+
377
+ (Note: these will always be relative to the `rpcRoutePrefix` option)
378
+ ```
379
+
380
+ By default all procedures will become post requests, but you can change this when creating a procedure:
381
+
382
+ ```ts
383
+ // procedures/users/getUser.rpc.ts
384
+ export default defineRpc({
385
+ method: "get",
386
+ // rest of config
387
+ });
388
+ ```
389
+
390
+ The supported HTTP methods are as follows:
391
+
392
+ - post
393
+ - get
394
+ - delete
395
+ - patch
396
+ - put
397
+
398
+ When using a get method the RPC params will be mapped as query parameters which will be coerced into their type using the `a.coerce` method from `arri-validate`. Get methods support all basic scalar types however arrays and nested objects are not supported.
399
+
400
+ ## Arri CLI
401
+
402
+ ```bash
403
+ # start the dev server
404
+ arri dev [flags]
405
+
406
+ # create a production build
407
+ arri build [flags]
155
408
 
156
- app.use(router);
409
+ # create a new project
410
+ arri init [dir]
157
411
  ```
158
412
 
159
413
  ## Developing
package/dist/cli.cjs CHANGED
@@ -45,6 +45,10 @@ const prettier__default = /*#__PURE__*/_interopDefaultCompat(prettier);
45
45
  const chokidar__default = /*#__PURE__*/_interopDefaultCompat(chokidar);
46
46
  const Degit__default = /*#__PURE__*/_interopDefaultCompat(Degit);
47
47
 
48
+ const DEFAULT_SERVER_ENTRY_FILE = "__default_arri_server.js";
49
+ const DEFAULT_CODEGEN_FILE = "__default_arri_codegen.js";
50
+ const SERVER_ENTRY_OUTPUT = "server.js";
51
+ const CODEGEN_OUTPUT = "codegen.js";
48
52
  async function setupWorkingDir(config) {
49
53
  const arriDir = path__default.resolve(config.rootDir, config.buildDir);
50
54
  const outDir = path__default.resolve(config.rootDir, ".output");
@@ -202,10 +206,14 @@ async function startBuild(config, skipCodeGen = false) {
202
206
  await bundleFiles(config);
203
207
  logger$2.log("Finished bundling");
204
208
  const clientCount = config.clientGenerators.length;
205
- const codegenModule = path__default.resolve(config.rootDir, ".output", "codegen.js");
209
+ const codegenModule = path__default.resolve(
210
+ config.rootDir,
211
+ ".output",
212
+ CODEGEN_OUTPUT
213
+ );
206
214
  if (clientCount > 0 && !skipCodeGen) {
207
215
  logger$2.log("Generating clients");
208
- node_child_process.execSync(`node ${codegenModule}`);
216
+ node_child_process.execSync(`node ${codegenModule}`, { env: process.env });
209
217
  const defJson = path__default.resolve(
210
218
  config.rootDir,
211
219
  ".output",
@@ -224,11 +232,9 @@ async function startBuild(config, skipCodeGen = false) {
224
232
  logger$2.log("Cleaning up files");
225
233
  await fs__default.rm(codegenModule);
226
234
  logger$2.log(
227
- `Build finished! You can start your server by running "node .output/server.js"`
235
+ `Build finished! You can start your server by running "node .output/${SERVER_ENTRY_OUTPUT}"`
228
236
  );
229
237
  }
230
- const BUILD_ENTRY_DEFAULT_FILE = "__default_arri_server.js";
231
- const CODEGEN_DEFAULT_FILE = "__default_arri_codegen.js";
232
238
  async function bundleFiles(config, allowCodegen = true) {
233
239
  if (allowCodegen) {
234
240
  await esbuild.build({
@@ -237,26 +243,27 @@ async function bundleFiles(config, allowCodegen = true) {
237
243
  path__default.resolve(
238
244
  config.rootDir,
239
245
  config.buildDir,
240
- CODEGEN_DEFAULT_FILE
246
+ DEFAULT_CODEGEN_FILE
241
247
  )
242
248
  ],
243
249
  platform: config.esbuild.platform ?? "node",
244
- target: config.esbuild.target ?? "node18",
250
+ target: config.esbuild.target ?? "node20",
251
+ packages: "external",
245
252
  bundle: true,
246
253
  format: "esm",
247
254
  sourcemap: false,
248
- minifyWhitespace: true,
255
+ minifyWhitespace: false,
249
256
  banner: {
250
257
  js: `import { createRequire as topLevelCreateRequire } from 'module';
251
258
  const require = topLevelCreateRequire(import.meta.url);`
252
259
  },
253
- outfile: path__default.resolve(config.rootDir, ".output", "codegen.js")
260
+ outfile: path__default.resolve(config.rootDir, ".output", CODEGEN_OUTPUT)
254
261
  });
255
262
  }
256
263
  let buildEntry = path__default.resolve(
257
264
  config.rootDir,
258
265
  config.buildDir,
259
- BUILD_ENTRY_DEFAULT_FILE
266
+ DEFAULT_SERVER_ENTRY_FILE
260
267
  );
261
268
  if (config.buildEntry) {
262
269
  const parts = config.buildEntry.split(".");
@@ -279,7 +286,7 @@ async function bundleFiles(config, allowCodegen = true) {
279
286
  const require = topLevelCreateRequire(import.meta.url);`
280
287
  },
281
288
  allowOverwrite: true,
282
- outfile: path__default.resolve(config.rootDir, ".output", "server.js")
289
+ outfile: path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT)
283
290
  });
284
291
  }
285
292
  async function createBuildEntryModule(config) {
@@ -310,7 +317,11 @@ void listen(toNodeListener(app.h3App), {
310
317
  public: true,
311
318
  });`;
312
319
  await fs__default.writeFile(
313
- path__default.resolve(config.rootDir, config.buildDir, BUILD_ENTRY_DEFAULT_FILE),
320
+ path__default.resolve(
321
+ config.rootDir,
322
+ config.buildDir,
323
+ DEFAULT_SERVER_ENTRY_FILE
324
+ ),
314
325
  virtualEntry
315
326
  );
316
327
  }
@@ -346,7 +357,7 @@ async function createBuildCodegenModule(config) {
346
357
  { tabWidth: 4, parser: "typescript" }
347
358
  );
348
359
  await fs__default.writeFile(
349
- path__default.resolve(config.rootDir, config.buildDir, CODEGEN_DEFAULT_FILE),
360
+ path__default.resolve(config.rootDir, config.buildDir, DEFAULT_CODEGEN_FILE),
350
361
  virtualModule
351
362
  );
352
363
  }
@@ -448,19 +459,26 @@ const dev = citty.defineCommand({
448
459
  await startDevServer(config$1);
449
460
  }
450
461
  });
451
- const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", "server.js"), {
452
- public: true,
453
- port: config.port,
454
- logger: logger$1,
455
- qr: showQr
456
- });
462
+ const startListener = (config, showQr = false) => listhen.listenAndWatch(
463
+ path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
464
+ {
465
+ public: true,
466
+ port: config.port,
467
+ logger: logger$1,
468
+ qr: showQr
469
+ }
470
+ );
457
471
  async function bundleFilesContext(config) {
458
472
  return await esbuild__namespace.context({
459
473
  ...config.esbuild,
460
474
  entryPoints: [
461
- path__default.resolve(config.rootDir, config.buildDir, "entry.js")
475
+ path__default.resolve(
476
+ config.rootDir,
477
+ config.buildDir,
478
+ DEFAULT_SERVER_ENTRY_FILE
479
+ )
462
480
  ],
463
- outfile: path__default.resolve(config.rootDir, ".output", "server.js"),
481
+ outfile: path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
464
482
  format: "esm",
465
483
  bundle: true,
466
484
  sourcemap: true,
@@ -581,7 +599,11 @@ for (const route of routes) {
581
599
 
582
600
  export default app.h3App;`;
583
601
  await fs__default.writeFile(
584
- path__default.resolve(config.rootDir, config.buildDir, "entry.js"),
602
+ path__default.resolve(
603
+ config.rootDir,
604
+ config.buildDir,
605
+ DEFAULT_SERVER_ENTRY_FILE
606
+ ),
585
607
  virtualEntry
586
608
  );
587
609
  }
package/dist/cli.mjs CHANGED
@@ -21,6 +21,10 @@ import Degit from 'degit';
21
21
  import 'h3';
22
22
  import 'arri-validate';
23
23
 
24
+ const DEFAULT_SERVER_ENTRY_FILE = "__default_arri_server.js";
25
+ const DEFAULT_CODEGEN_FILE = "__default_arri_codegen.js";
26
+ const SERVER_ENTRY_OUTPUT = "server.js";
27
+ const CODEGEN_OUTPUT = "codegen.js";
24
28
  async function setupWorkingDir(config) {
25
29
  const arriDir = path.resolve(config.rootDir, config.buildDir);
26
30
  const outDir = path.resolve(config.rootDir, ".output");
@@ -178,10 +182,14 @@ async function startBuild(config, skipCodeGen = false) {
178
182
  await bundleFiles(config);
179
183
  logger$2.log("Finished bundling");
180
184
  const clientCount = config.clientGenerators.length;
181
- const codegenModule = path.resolve(config.rootDir, ".output", "codegen.js");
185
+ const codegenModule = path.resolve(
186
+ config.rootDir,
187
+ ".output",
188
+ CODEGEN_OUTPUT
189
+ );
182
190
  if (clientCount > 0 && !skipCodeGen) {
183
191
  logger$2.log("Generating clients");
184
- execSync(`node ${codegenModule}`);
192
+ execSync(`node ${codegenModule}`, { env: process.env });
185
193
  const defJson = path.resolve(
186
194
  config.rootDir,
187
195
  ".output",
@@ -200,11 +208,9 @@ async function startBuild(config, skipCodeGen = false) {
200
208
  logger$2.log("Cleaning up files");
201
209
  await fs.rm(codegenModule);
202
210
  logger$2.log(
203
- `Build finished! You can start your server by running "node .output/server.js"`
211
+ `Build finished! You can start your server by running "node .output/${SERVER_ENTRY_OUTPUT}"`
204
212
  );
205
213
  }
206
- const BUILD_ENTRY_DEFAULT_FILE = "__default_arri_server.js";
207
- const CODEGEN_DEFAULT_FILE = "__default_arri_codegen.js";
208
214
  async function bundleFiles(config, allowCodegen = true) {
209
215
  if (allowCodegen) {
210
216
  await build$1({
@@ -213,26 +219,27 @@ async function bundleFiles(config, allowCodegen = true) {
213
219
  path.resolve(
214
220
  config.rootDir,
215
221
  config.buildDir,
216
- CODEGEN_DEFAULT_FILE
222
+ DEFAULT_CODEGEN_FILE
217
223
  )
218
224
  ],
219
225
  platform: config.esbuild.platform ?? "node",
220
- target: config.esbuild.target ?? "node18",
226
+ target: config.esbuild.target ?? "node20",
227
+ packages: "external",
221
228
  bundle: true,
222
229
  format: "esm",
223
230
  sourcemap: false,
224
- minifyWhitespace: true,
231
+ minifyWhitespace: false,
225
232
  banner: {
226
233
  js: `import { createRequire as topLevelCreateRequire } from 'module';
227
234
  const require = topLevelCreateRequire(import.meta.url);`
228
235
  },
229
- outfile: path.resolve(config.rootDir, ".output", "codegen.js")
236
+ outfile: path.resolve(config.rootDir, ".output", CODEGEN_OUTPUT)
230
237
  });
231
238
  }
232
239
  let buildEntry = path.resolve(
233
240
  config.rootDir,
234
241
  config.buildDir,
235
- BUILD_ENTRY_DEFAULT_FILE
242
+ DEFAULT_SERVER_ENTRY_FILE
236
243
  );
237
244
  if (config.buildEntry) {
238
245
  const parts = config.buildEntry.split(".");
@@ -255,7 +262,7 @@ async function bundleFiles(config, allowCodegen = true) {
255
262
  const require = topLevelCreateRequire(import.meta.url);`
256
263
  },
257
264
  allowOverwrite: true,
258
- outfile: path.resolve(config.rootDir, ".output", "server.js")
265
+ outfile: path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT)
259
266
  });
260
267
  }
261
268
  async function createBuildEntryModule(config) {
@@ -286,7 +293,11 @@ void listen(toNodeListener(app.h3App), {
286
293
  public: true,
287
294
  });`;
288
295
  await fs.writeFile(
289
- path.resolve(config.rootDir, config.buildDir, BUILD_ENTRY_DEFAULT_FILE),
296
+ path.resolve(
297
+ config.rootDir,
298
+ config.buildDir,
299
+ DEFAULT_SERVER_ENTRY_FILE
300
+ ),
290
301
  virtualEntry
291
302
  );
292
303
  }
@@ -322,7 +333,7 @@ async function createBuildCodegenModule(config) {
322
333
  { tabWidth: 4, parser: "typescript" }
323
334
  );
324
335
  await fs.writeFile(
325
- path.resolve(config.rootDir, config.buildDir, CODEGEN_DEFAULT_FILE),
336
+ path.resolve(config.rootDir, config.buildDir, DEFAULT_CODEGEN_FILE),
326
337
  virtualModule
327
338
  );
328
339
  }
@@ -424,19 +435,26 @@ const dev = defineCommand({
424
435
  await startDevServer(config);
425
436
  }
426
437
  });
427
- const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", "server.js"), {
428
- public: true,
429
- port: config.port,
430
- logger: logger$1,
431
- qr: showQr
432
- });
438
+ const startListener = (config, showQr = false) => listenAndWatch(
439
+ path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
440
+ {
441
+ public: true,
442
+ port: config.port,
443
+ logger: logger$1,
444
+ qr: showQr
445
+ }
446
+ );
433
447
  async function bundleFilesContext(config) {
434
448
  return await esbuild.context({
435
449
  ...config.esbuild,
436
450
  entryPoints: [
437
- path.resolve(config.rootDir, config.buildDir, "entry.js")
451
+ path.resolve(
452
+ config.rootDir,
453
+ config.buildDir,
454
+ DEFAULT_SERVER_ENTRY_FILE
455
+ )
438
456
  ],
439
- outfile: path.resolve(config.rootDir, ".output", "server.js"),
457
+ outfile: path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
440
458
  format: "esm",
441
459
  bundle: true,
442
460
  sourcemap: true,
@@ -557,7 +575,11 @@ for (const route of routes) {
557
575
 
558
576
  export default app.h3App;`;
559
577
  await fs.writeFile(
560
- path.resolve(config.rootDir, config.buildDir, "entry.js"),
578
+ path.resolve(
579
+ config.rootDir,
580
+ config.buildDir,
581
+ DEFAULT_SERVER_ENTRY_FILE
582
+ ),
561
583
  virtualEntry
562
584
  );
563
585
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.12.0",
3
+ "version": "0.12.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -30,10 +30,10 @@
30
30
  "pathe": "^1.1.1",
31
31
  "prettier": "^3.0.3",
32
32
  "scule": "^1.0.0",
33
- "arri-codegen-dart": "0.12.0",
34
- "arri-codegen-ts": "0.12.0",
35
- "arri-codegen-utils": "0.12.0",
36
- "arri-validate": "0.12.0"
33
+ "arri-codegen-dart": "0.12.4",
34
+ "arri-codegen-utils": "0.12.4",
35
+ "arri-codegen-ts": "0.12.4",
36
+ "arri-validate": "0.12.4"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "listhen": "1.x"