arri 0.11.3 → 0.12.2

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
@@ -11,7 +11,7 @@ const consola = require('consola');
11
11
  const esbuild = require('esbuild');
12
12
  const path = require('pathe');
13
13
  const prettier = require('prettier');
14
- const config = require('./shared/arri.a90e9723.cjs');
14
+ const config = require('./shared/arri.fa32b1ba.cjs');
15
15
  const globby = require('globby');
16
16
  const scule = require('scule');
17
17
  const arriCodegenDart = require('arri-codegen-dart');
@@ -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");
@@ -160,7 +164,7 @@ async function transpileFiles(config) {
160
164
  outdir: outDir,
161
165
  bundle: false,
162
166
  format: "esm",
163
- target: "node18",
167
+ target: "node20",
164
168
  platform: "node"
165
169
  });
166
170
  }
@@ -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,7 +232,7 @@ 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
238
  async function bundleFiles(config, allowCodegen = true) {
@@ -232,26 +240,39 @@ async function bundleFiles(config, allowCodegen = true) {
232
240
  await esbuild.build({
233
241
  ...config.esbuild,
234
242
  entryPoints: [
235
- path__default.resolve(config.rootDir, config.buildDir, "codegen.js")
243
+ path__default.resolve(
244
+ config.rootDir,
245
+ config.buildDir,
246
+ DEFAULT_CODEGEN_FILE
247
+ )
236
248
  ],
237
249
  platform: config.esbuild.platform ?? "node",
238
- target: config.esbuild.target ?? "node18",
250
+ target: config.esbuild.target ?? "node20",
239
251
  bundle: true,
240
252
  format: "esm",
241
253
  sourcemap: false,
242
- minifyWhitespace: true,
254
+ minifyWhitespace: false,
243
255
  banner: {
244
256
  js: `import { createRequire as topLevelCreateRequire } from 'module';
245
257
  const require = topLevelCreateRequire(import.meta.url);`
246
258
  },
247
- outdir: path__default.resolve(config.rootDir, ".output")
259
+ outfile: path__default.resolve(config.rootDir, ".output", CODEGEN_OUTPUT)
248
260
  });
249
261
  }
262
+ let buildEntry = path__default.resolve(
263
+ config.rootDir,
264
+ config.buildDir,
265
+ DEFAULT_SERVER_ENTRY_FILE
266
+ );
267
+ if (config.buildEntry) {
268
+ const parts = config.buildEntry.split(".");
269
+ parts.pop();
270
+ const mergedParts = `${parts.join(".")}.js`;
271
+ buildEntry = path__default.resolve(config.rootDir, config.buildDir, mergedParts);
272
+ }
250
273
  await esbuild.build({
251
274
  ...config.esbuild,
252
- entryPoints: [
253
- path__default.resolve(config.rootDir, config.buildDir, "server.js")
254
- ],
275
+ entryPoints: [buildEntry],
255
276
  platform: config.esbuild.platform ?? "node",
256
277
  target: config.esbuild.target ?? "node20",
257
278
  bundle: true,
@@ -264,10 +285,13 @@ async function bundleFiles(config, allowCodegen = true) {
264
285
  const require = topLevelCreateRequire(import.meta.url);`
265
286
  },
266
287
  allowOverwrite: true,
267
- outdir: path__default.resolve(config.rootDir, ".output")
288
+ outfile: path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT)
268
289
  });
269
290
  }
270
291
  async function createBuildEntryModule(config) {
292
+ if (config.buildEntry) {
293
+ return;
294
+ }
271
295
  const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
272
296
  const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
273
297
  appImportParts.pop();
@@ -289,9 +313,14 @@ for (const route of routes) {
289
313
 
290
314
  void listen(toNodeListener(app.h3App), {
291
315
  port: process.env.PORT ?? ${config.port},
316
+ public: true,
292
317
  });`;
293
318
  await fs__default.writeFile(
294
- path__default.resolve(config.rootDir, config.buildDir, "server.js"),
319
+ path__default.resolve(
320
+ config.rootDir,
321
+ config.buildDir,
322
+ DEFAULT_SERVER_ENTRY_FILE
323
+ ),
295
324
  virtualEntry
296
325
  );
297
326
  }
@@ -327,7 +356,7 @@ async function createBuildCodegenModule(config) {
327
356
  { tabWidth: 4, parser: "typescript" }
328
357
  );
329
358
  await fs__default.writeFile(
330
- path__default.resolve(config.rootDir, config.buildDir, "codegen.js"),
359
+ path__default.resolve(config.rootDir, config.buildDir, DEFAULT_CODEGEN_FILE),
331
360
  virtualModule
332
361
  );
333
362
  }
@@ -429,19 +458,26 @@ const dev = citty.defineCommand({
429
458
  await startDevServer(config$1);
430
459
  }
431
460
  });
432
- const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", "server.js"), {
433
- public: true,
434
- port: config.port,
435
- logger: logger$1,
436
- qr: showQr
437
- });
461
+ const startListener = (config, showQr = false) => listhen.listenAndWatch(
462
+ path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
463
+ {
464
+ public: true,
465
+ port: config.port,
466
+ logger: logger$1,
467
+ qr: showQr
468
+ }
469
+ );
438
470
  async function bundleFilesContext(config) {
439
471
  return await esbuild__namespace.context({
440
472
  ...config.esbuild,
441
473
  entryPoints: [
442
- path__default.resolve(config.rootDir, config.buildDir, "entry.js")
474
+ path__default.resolve(
475
+ config.rootDir,
476
+ config.buildDir,
477
+ DEFAULT_SERVER_ENTRY_FILE
478
+ )
443
479
  ],
444
- outfile: path__default.resolve(config.rootDir, ".output", "server.js"),
480
+ outfile: path__default.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
445
481
  format: "esm",
446
482
  bundle: true,
447
483
  sourcemap: true,
@@ -562,7 +598,11 @@ for (const route of routes) {
562
598
 
563
599
  export default app.h3App;`;
564
600
  await fs__default.writeFile(
565
- path__default.resolve(config.rootDir, config.buildDir, "entry.js"),
601
+ path__default.resolve(
602
+ config.rootDir,
603
+ config.buildDir,
604
+ DEFAULT_SERVER_ENTRY_FILE
605
+ ),
566
606
  virtualEntry
567
607
  );
568
608
  }
package/dist/cli.mjs CHANGED
@@ -10,7 +10,7 @@ import * as esbuild from 'esbuild';
10
10
  import { build as build$1 } from 'esbuild';
11
11
  import path from 'pathe';
12
12
  import prettier from 'prettier';
13
- import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.537f5e35.mjs';
13
+ import { n as defaultConfig, m as isResolvedArriConfig, a as DEV_DEFINITION_ENDPOINT } from './shared/arri.4d91d9b0.mjs';
14
14
  import { globby } from 'globby';
15
15
  import { camelCase, kebabCase } from 'scule';
16
16
  import { dartClientGenerator } from 'arri-codegen-dart';
@@ -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");
@@ -136,7 +140,7 @@ async function transpileFiles(config) {
136
140
  outdir: outDir,
137
141
  bundle: false,
138
142
  format: "esm",
139
- target: "node18",
143
+ target: "node20",
140
144
  platform: "node"
141
145
  });
142
146
  }
@@ -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,7 +208,7 @@ 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
214
  async function bundleFiles(config, allowCodegen = true) {
@@ -208,26 +216,39 @@ async function bundleFiles(config, allowCodegen = true) {
208
216
  await build$1({
209
217
  ...config.esbuild,
210
218
  entryPoints: [
211
- path.resolve(config.rootDir, config.buildDir, "codegen.js")
219
+ path.resolve(
220
+ config.rootDir,
221
+ config.buildDir,
222
+ DEFAULT_CODEGEN_FILE
223
+ )
212
224
  ],
213
225
  platform: config.esbuild.platform ?? "node",
214
- target: config.esbuild.target ?? "node18",
226
+ target: config.esbuild.target ?? "node20",
215
227
  bundle: true,
216
228
  format: "esm",
217
229
  sourcemap: false,
218
- minifyWhitespace: true,
230
+ minifyWhitespace: false,
219
231
  banner: {
220
232
  js: `import { createRequire as topLevelCreateRequire } from 'module';
221
233
  const require = topLevelCreateRequire(import.meta.url);`
222
234
  },
223
- outdir: path.resolve(config.rootDir, ".output")
235
+ outfile: path.resolve(config.rootDir, ".output", CODEGEN_OUTPUT)
224
236
  });
225
237
  }
238
+ let buildEntry = path.resolve(
239
+ config.rootDir,
240
+ config.buildDir,
241
+ DEFAULT_SERVER_ENTRY_FILE
242
+ );
243
+ if (config.buildEntry) {
244
+ const parts = config.buildEntry.split(".");
245
+ parts.pop();
246
+ const mergedParts = `${parts.join(".")}.js`;
247
+ buildEntry = path.resolve(config.rootDir, config.buildDir, mergedParts);
248
+ }
226
249
  await build$1({
227
250
  ...config.esbuild,
228
- entryPoints: [
229
- path.resolve(config.rootDir, config.buildDir, "server.js")
230
- ],
251
+ entryPoints: [buildEntry],
231
252
  platform: config.esbuild.platform ?? "node",
232
253
  target: config.esbuild.target ?? "node20",
233
254
  bundle: true,
@@ -240,10 +261,13 @@ async function bundleFiles(config, allowCodegen = true) {
240
261
  const require = topLevelCreateRequire(import.meta.url);`
241
262
  },
242
263
  allowOverwrite: true,
243
- outdir: path.resolve(config.rootDir, ".output")
264
+ outfile: path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT)
244
265
  });
245
266
  }
246
267
  async function createBuildEntryModule(config) {
268
+ if (config.buildEntry) {
269
+ return;
270
+ }
247
271
  const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
248
272
  const appImportParts = path.relative(path.resolve(config.rootDir, config.srcDir), appModule).split(".");
249
273
  appImportParts.pop();
@@ -265,9 +289,14 @@ for (const route of routes) {
265
289
 
266
290
  void listen(toNodeListener(app.h3App), {
267
291
  port: process.env.PORT ?? ${config.port},
292
+ public: true,
268
293
  });`;
269
294
  await fs.writeFile(
270
- path.resolve(config.rootDir, config.buildDir, "server.js"),
295
+ path.resolve(
296
+ config.rootDir,
297
+ config.buildDir,
298
+ DEFAULT_SERVER_ENTRY_FILE
299
+ ),
271
300
  virtualEntry
272
301
  );
273
302
  }
@@ -303,7 +332,7 @@ async function createBuildCodegenModule(config) {
303
332
  { tabWidth: 4, parser: "typescript" }
304
333
  );
305
334
  await fs.writeFile(
306
- path.resolve(config.rootDir, config.buildDir, "codegen.js"),
335
+ path.resolve(config.rootDir, config.buildDir, DEFAULT_CODEGEN_FILE),
307
336
  virtualModule
308
337
  );
309
338
  }
@@ -405,19 +434,26 @@ const dev = defineCommand({
405
434
  await startDevServer(config);
406
435
  }
407
436
  });
408
- const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", "server.js"), {
409
- public: true,
410
- port: config.port,
411
- logger: logger$1,
412
- qr: showQr
413
- });
437
+ const startListener = (config, showQr = false) => listenAndWatch(
438
+ path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
439
+ {
440
+ public: true,
441
+ port: config.port,
442
+ logger: logger$1,
443
+ qr: showQr
444
+ }
445
+ );
414
446
  async function bundleFilesContext(config) {
415
447
  return await esbuild.context({
416
448
  ...config.esbuild,
417
449
  entryPoints: [
418
- path.resolve(config.rootDir, config.buildDir, "entry.js")
450
+ path.resolve(
451
+ config.rootDir,
452
+ config.buildDir,
453
+ DEFAULT_SERVER_ENTRY_FILE
454
+ )
419
455
  ],
420
- outfile: path.resolve(config.rootDir, ".output", "server.js"),
456
+ outfile: path.resolve(config.rootDir, ".output", SERVER_ENTRY_OUTPUT),
421
457
  format: "esm",
422
458
  bundle: true,
423
459
  sourcemap: true,
@@ -538,7 +574,11 @@ for (const route of routes) {
538
574
 
539
575
  export default app.h3App;`;
540
576
  await fs.writeFile(
541
- path.resolve(config.rootDir, config.buildDir, "entry.js"),
577
+ path.resolve(
578
+ config.rootDir,
579
+ config.buildDir,
580
+ DEFAULT_SERVER_ENTRY_FILE
581
+ ),
542
582
  virtualEntry
543
583
  );
544
584
  }
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const config = require('./shared/arri.a90e9723.cjs');
3
+ const config = require('./shared/arri.fa32b1ba.cjs');
4
4
  const h3 = require('h3');
5
5
  require('arri-validate');
6
6
  require('arri-codegen-utils');
package/dist/index.d.cts CHANGED
@@ -152,6 +152,7 @@ declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOption
152
152
  interface ArriConfig {
153
153
  port: number;
154
154
  entry: string;
155
+ buildEntry?: string;
155
156
  rootDir?: string;
156
157
  srcDir?: string;
157
158
  procedureDir?: string | false;
package/dist/index.d.mts CHANGED
@@ -152,6 +152,7 @@ declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOption
152
152
  interface ArriConfig {
153
153
  port: number;
154
154
  entry: string;
155
+ buildEntry?: string;
155
156
  rootDir?: string;
156
157
  srcDir?: string;
157
158
  procedureDir?: string | false;
package/dist/index.d.ts CHANGED
@@ -152,6 +152,7 @@ declare function handleH3Error(err: unknown, event: H3Event, onError: ArriOption
152
152
  interface ArriConfig {
153
153
  port: number;
154
154
  entry: string;
155
+ buildEntry?: string;
155
156
  rootDir?: string;
156
157
  srcDir?: string;
157
158
  procedureDir?: string | false;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, c as createRpcDefinition, n as defaultConfig, o as defineConfig, h as defineError, q as defineRoute, d as defineRpc, j as errorResponseFromValidationErrors, e as getRpcParamName, g as getRpcPath, f as getRpcResponseName, k as handleH3Error, t as handleRoute, l as isArriConfig, m as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, s as registerRoute, r as registerRpc } from './shared/arri.537f5e35.mjs';
1
+ export { A as ArriApp, p as ArriRouter, a as DEV_DEFINITION_ENDPOINT, D as DEV_ENDPOINT_ROOT, E as ErrorResponse, c as createRpcDefinition, n as defaultConfig, o as defineConfig, h as defineError, q as defineRoute, d as defineRpc, j as errorResponseFromValidationErrors, e as getRpcParamName, g as getRpcPath, f as getRpcResponseName, k as handleH3Error, t as handleRoute, l as isArriConfig, m as isResolvedArriConfig, b as isRpc, i as isRpcParamSchema, s as registerRoute, r as registerRpc } from './shared/arri.4d91d9b0.mjs';
2
2
  export * from 'h3';
3
3
  import 'arri-validate';
4
4
  import 'arri-codegen-utils';
@@ -713,6 +713,7 @@ const defaultConfig = {
713
713
  procedureGlobPatterns: ["**/*.rpc.ts"],
714
714
  clientGenerators: [],
715
715
  buildDir: ".arri",
716
+ buildEntry: "",
716
717
  esbuild: {}
717
718
  };
718
719
  function defineConfig(config) {
@@ -725,7 +726,8 @@ function defineConfig(config) {
725
726
  procedureGlobPatterns: config.procedureGlobPatterns ?? defaultConfig.procedureGlobPatterns,
726
727
  clientGenerators: config.clientGenerators ?? defaultConfig.clientGenerators,
727
728
  buildDir: config.buildDir ?? defaultConfig.buildDir,
728
- esbuild: config.esbuild ?? defaultConfig.esbuild
729
+ esbuild: config.esbuild ?? defaultConfig.esbuild,
730
+ buildEntry: config.buildEntry ?? ""
729
731
  };
730
732
  }
731
733
 
@@ -715,6 +715,7 @@ const defaultConfig = {
715
715
  procedureGlobPatterns: ["**/*.rpc.ts"],
716
716
  clientGenerators: [],
717
717
  buildDir: ".arri",
718
+ buildEntry: "",
718
719
  esbuild: {}
719
720
  };
720
721
  function defineConfig(config) {
@@ -727,7 +728,8 @@ function defineConfig(config) {
727
728
  procedureGlobPatterns: config.procedureGlobPatterns ?? defaultConfig.procedureGlobPatterns,
728
729
  clientGenerators: config.clientGenerators ?? defaultConfig.clientGenerators,
729
730
  buildDir: config.buildDir ?? defaultConfig.buildDir,
730
- esbuild: config.esbuild ?? defaultConfig.esbuild
731
+ esbuild: config.esbuild ?? defaultConfig.esbuild,
732
+ buildEntry: config.buildEntry ?? ""
731
733
  };
732
734
  }
733
735
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.11.3",
3
+ "version": "0.12.2",
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.11.3",
34
- "arri-codegen-utils": "0.11.3",
35
- "arri-codegen-ts": "0.11.3",
36
- "arri-validate": "0.11.3"
33
+ "arri-codegen-dart": "0.12.2",
34
+ "arri-codegen-utils": "0.12.2",
35
+ "arri-codegen-ts": "0.12.2",
36
+ "arri-validate": "0.12.2"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "listhen": "1.x"