arri 0.58.1 → 0.60.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -74,9 +74,11 @@ For full details visit the [server docs](https://github.com/modiimedia/arri/blob
74
74
  import { defineConfig } from "arri";
75
75
 
76
76
  export default defineConfig({
77
- srcDir: "src",
78
- entry: "app.ts",
79
- port: 3000,
77
+ server: servers.tsServer({
78
+ srcDir: "src",
79
+ entry: "app.ts",
80
+ port: 3000,
81
+ }),
80
82
  generators: [
81
83
  // client generators go here (can be imported from arri)
82
84
  ],
package/dist/cli.cjs CHANGED
@@ -2,36 +2,29 @@
2
2
  'use strict';
3
3
 
4
4
  const citty = require('citty');
5
- const node_child_process = require('node:child_process');
5
+ const c12 = require('c12');
6
+ const common = require('./shared/arri.7f2f73b2.cjs');
6
7
  const fs = require('node:fs');
7
- const fs$1 = require('node:fs/promises');
8
8
  const codegenUtils = require('@arrirpc/codegen-utils');
9
- const c12 = require('c12');
10
- const esbuild = require('esbuild');
11
- const esbuildPluginReplace = require('esbuild-plugin-replace');
12
- const path = require('pathe');
13
- const prettier = require('prettier');
14
- const dev = require('./shared/arri.a671ac34.cjs');
15
9
  const ofetch = require('@joshmossas/ofetch');
16
10
  const chokidar = require('chokidar');
11
+ const path = require('pathe');
17
12
  const Degit = require('degit');
18
13
  const enquirer = require('enquirer');
14
+ const prettier = require('prettier');
19
15
  const schema = require('@arrirpc/schema');
20
16
  const consola = require('consola');
21
17
  const promises = require('fs/promises');
22
18
  const node_url = require('node:url');
23
- require('@joshmossas/listhen');
24
- require('h3');
25
19
 
26
20
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
27
21
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
28
22
 
29
- const fs__default$1 = /*#__PURE__*/_interopDefaultCompat(fs);
30
- const fs__default = /*#__PURE__*/_interopDefaultCompat(fs$1);
23
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
31
24
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
32
- const prettier__default = /*#__PURE__*/_interopDefaultCompat(prettier);
33
25
  const Degit__default = /*#__PURE__*/_interopDefaultCompat(Degit);
34
26
  const enquirer__default = /*#__PURE__*/_interopDefaultCompat(enquirer);
27
+ const prettier__default = /*#__PURE__*/_interopDefaultCompat(prettier);
35
28
  const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
36
29
 
37
30
  const build = citty.defineCommand({
@@ -50,181 +43,35 @@ const build = citty.defineCommand({
50
43
  default: false
51
44
  }
52
45
  },
53
- async run({ args }) {
46
+ async run({ args, rawArgs }) {
54
47
  const { config } = await c12.loadConfig({
55
- configFile: args.config,
56
- defaultConfig: dev.defaultConfig
48
+ configFile: args.config
57
49
  });
58
50
  if (!config) {
59
51
  throw new Error("Unable to find arri config");
60
52
  }
61
- const appEntry = path__default.resolve(
62
- config.rootDir,
63
- config.srcDir,
64
- config.entry
65
- );
66
- if (!fs.existsSync(appEntry)) {
67
- throw new Error(`Unable to find entry at ${appEntry}`);
53
+ if (!common.isArriConfig(config)) {
54
+ throw new Error(`Invalid arri config at ${args.config}`);
68
55
  }
69
- await startBuild(config, args.skipCodegen);
70
- }
71
- });
72
- async function startBuild(config, skipCodeGen = false) {
73
- dev.logger.log("Bundling server....");
74
- const appEntry = path__default.resolve(config.rootDir, config.srcDir, config.entry);
75
- if (!fs.existsSync(path__default.resolve(config.rootDir, config.srcDir, config.entry))) {
76
- dev.logger.error(`Unabled to find entry at ${appEntry}`);
77
- process.exit(1);
78
- }
79
- await dev.setupWorkingDir(config);
80
- await Promise.all([
81
- dev.createAppWithRoutesModule(config),
82
- createServerEntryFile(config),
83
- createCodegenEntryFile(config)
84
- ]);
85
- await bundleAppEntry(config);
86
- dev.logger.log("Finished bundling");
87
- const clientCount = config.generators.length;
88
- const codegenModule = path__default.resolve(config.rootDir, ".output", dev.OUT_CODEGEN);
89
- if (!skipCodeGen) {
90
- dev.logger.log("Generating Arri app definition (__definition.json)");
91
- node_child_process.execSync(`node ${codegenModule}`, { env: process.env });
92
- const defJson = path__default.resolve(
93
- config.rootDir,
94
- ".output",
95
- "__definition.json"
96
- );
97
- const def = JSON.parse(fs.readFileSync(defJson, { encoding: "utf-8" }));
98
- if (codegenUtils.isAppDefinition(def) && clientCount > 0) {
99
- const startTime = (/* @__PURE__ */ new Date()).getTime();
100
- dev.logger.log(`Generating ${clientCount} client(s)...`);
101
- await Promise.all(
102
- config.generators.map((plugin) => plugin.generator(def))
103
- );
104
- dev.logger.log(
105
- `${clientCount} client(s) generated in ${( new Date()).getTime() - startTime}ms`
106
- );
107
- } else {
108
- dev.logger.warn(
109
- "No client generators specified. Skipping client codegen."
56
+ if (!config.server) {
57
+ throw new Error(
58
+ "No server specified in config file. Cannot run build."
110
59
  );
111
60
  }
112
- } else {
113
- dev.logger.log("Skipping codegen");
114
- }
115
- dev.logger.log("Cleaning up files");
116
- await fs__default.rm(codegenModule);
117
- dev.logger.success(
118
- `Build finished! You can start your server by running "node .output/${dev.OUT_SERVER_ENTRY}"`
119
- );
120
- }
121
- async function bundleAppEntry(config, _allowCodegen = true) {
122
- const appEntry = path__default.resolve(
123
- config.rootDir,
124
- config.buildDir,
125
- dev.GEN_APP_FILE
126
- );
127
- await esbuild.build({
128
- ...config.esbuild,
129
- entryPoints: [appEntry],
130
- platform: config.esbuild.platform ?? "node",
131
- target: config.esbuild.target ?? "node20",
132
- bundle: true,
133
- packages: "external",
134
- format: "esm",
135
- sourcemap: config.esbuild.sourcemap ?? true,
136
- minify: config.esbuild.minify ?? true,
137
- banner: {
138
- js: `import { createRequire as topLevelCreateRequire } from 'module';
139
- const require = topLevelCreateRequire(import.meta.url);`
140
- },
141
- allowOverwrite: true,
142
- outfile: path__default.resolve(config.rootDir, ".output", dev.OUT_APP_FILE)
143
- });
144
- }
145
- async function createServerEntryFile(config) {
146
- if (config.serverEntry) {
147
- const buildEntry = path__default.resolve(
148
- config.rootDir,
149
- config.srcDir,
150
- config.serverEntry
151
- );
152
- await esbuild.build({
153
- ...config.esbuild,
154
- entryPoints: [buildEntry],
155
- platform: config.esbuild.platform ?? "node",
156
- target: config.esbuild.target ?? "node20",
157
- bundle: false,
158
- packages: "external",
159
- format: "esm",
160
- sourcemap: true,
161
- minifyWhitespace: true,
162
- banner: {
163
- js: `import { createRequire as topLevelCreateRequire } from 'module';
164
- const require = topLevelCreateRequire(import.meta.url);`
165
- },
166
- plugins: [esbuildPluginReplace.replace({ "virtual:arri/app": "./app.mjs" })],
167
- allowOverwrite: true,
168
- outfile: path__default.resolve(config.rootDir, ".output", dev.OUT_SERVER_ENTRY)
61
+ const subArgs = config.server.buildArgs ?? {};
62
+ subArgs.skipCodegen = {
63
+ type: "boolean",
64
+ default: false
65
+ };
66
+ const subCommand = citty.defineCommand({
67
+ args: subArgs,
68
+ async run({ args: args2 }) {
69
+ await config.server?.buildFn(args2, config.generators);
70
+ }
169
71
  });
170
- return;
72
+ await citty.runCommand(subCommand, { rawArgs });
171
73
  }
172
- const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
173
- const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
174
- appImportParts.pop();
175
- let httpsString = ``;
176
- if (config.https === true) {
177
- httpsString = `https: true,`;
178
- } else if (typeof config.https === "object") {
179
- httpsString = `https: { cert: '${config.https.cert}', key: '${config.https.key}', passphrase: ${config.https.passphrase ? `'${config.https.passphrase}'` : "undefined"}},`;
180
- }
181
- const virtualEntry = `import { toNodeListener } from '@arrirpc/server';
182
- import { listen } from '@joshmossas/listhen';
183
- import app from './${dev.OUT_APP_FILE}';
184
-
185
- void listen(toNodeListener(app.h3App), {
186
- port: process.env.PORT ?? ${config.port},
187
- public: true,
188
- ws: {
189
- resolve(info) {
190
- if (app.h3App.websocket?.resolve) {
191
- return app.h3App.websocket.resolve(info);
192
- }
193
- return app.h3App.websocket?.hooks ?? app.h3App.handler?.__websocket__ ?? {};
194
- }
195
- },
196
- http2: ${config.http2 ?? false},
197
- ${httpsString}
198
- });`;
199
- await fs__default.writeFile(
200
- path__default.resolve(config.rootDir, ".output", dev.OUT_SERVER_ENTRY),
201
- virtualEntry
202
- );
203
- }
204
- async function createCodegenEntryFile(config) {
205
- const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
206
- const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
207
- appImportParts.pop();
208
- const virtualModule = await prettier__default.format(
209
- `
210
- import { writeFileSync } from 'node:fs';
211
- import path from 'pathe';
212
- import app from './${dev.OUT_APP_FILE}';
213
-
214
- const __dirname = new URL(".", import.meta.url).pathname;
215
- const def = app.getAppDefinition();
216
- writeFileSync(
217
- path.resolve(__dirname, "../.output", "__definition.json"),
218
- JSON.stringify(def),
219
- );
220
- process.exit(0);`,
221
- { tabWidth: 4, parser: "typescript" }
222
- );
223
- await fs__default.writeFile(
224
- path__default.resolve(config.rootDir, ".output", dev.OUT_CODEGEN),
225
- virtualModule
226
- );
227
- }
74
+ });
228
75
 
229
76
  const codegen = citty.defineCommand({
230
77
  meta: {
@@ -249,8 +96,8 @@ const codegen = citty.defineCommand({
249
96
  }
250
97
  },
251
98
  async run({ args }) {
252
- if (!fs__default$1.existsSync(path__default.resolve(args.config))) {
253
- dev.logger.error(
99
+ if (!fs__default.existsSync(path__default.resolve(args.config))) {
100
+ common.logger.error(
254
101
  `Unable to load arri config at ${args.config}. Please specify a valid config path with --config`
255
102
  );
256
103
  process.exit(1);
@@ -258,12 +105,12 @@ const codegen = citty.defineCommand({
258
105
  const { config } = await c12.loadConfig({
259
106
  configFile: path__default.resolve(args.config)
260
107
  });
261
- if (!dev.isArriConfig(config)) {
262
- dev.logger.error(`Invalid arri config at ${args.config}`);
108
+ if (!common.isArriConfig(config)) {
109
+ common.logger.error(`Invalid arri config at ${args.config}`);
263
110
  process.exit(1);
264
111
  }
265
112
  if (!config.generators?.length) {
266
- dev.logger.error(`No generators specified in ${args.config}`);
113
+ common.logger.error(`No generators specified in ${args.config}`);
267
114
  process.exit(1);
268
115
  }
269
116
  const isUrl = args.schema.startsWith("http://") || args.schema.startsWith("https://");
@@ -283,7 +130,7 @@ const codegen = citty.defineCommand({
283
130
  if (!args.watch) {
284
131
  throw err;
285
132
  }
286
- dev.logger.error(err);
133
+ common.logger.error(err);
287
134
  }
288
135
  }
289
136
  if (!def && !args.watch) {
@@ -292,48 +139,48 @@ const codegen = citty.defineCommand({
292
139
  if (def) {
293
140
  const initialStartTime = /* @__PURE__ */ new Date();
294
141
  await runGenerators(def, config.generators ?? []);
295
- dev.logger.success(
142
+ common.logger.success(
296
143
  `Generators completed in ${( new Date()).getTime() - initialStartTime.getTime()}ms`
297
144
  );
298
145
  }
299
146
  if (!args.watch)
300
147
  process.exit(0);
301
148
  const watcher = chokidar.watch(args.schema, { ignoreInitial: true });
302
- dev.logger.info(`Watching ${args.schema} for changes...`);
149
+ common.logger.info(`Watching ${args.schema} for changes...`);
303
150
  watcher.on("add", async (_, __) => {
304
151
  try {
305
- dev.logger.info(`Change detected`);
152
+ common.logger.info(`Change detected`);
306
153
  const startTime = /* @__PURE__ */ new Date();
307
154
  await runGenerators(
308
155
  await getAppDefinitionFromFile(args.schema),
309
156
  config.generators ?? []
310
157
  );
311
- dev.logger.success(
158
+ common.logger.success(
312
159
  `Generators completed in ${( new Date()).getTime() - startTime.getTime()}ms`
313
160
  );
314
161
  } catch (err) {
315
- dev.logger.error(err);
162
+ common.logger.error(err);
316
163
  }
317
164
  });
318
165
  watcher.on("change", async (_, __) => {
319
166
  try {
320
- dev.logger.info(`Change detected in AppDefinition file.`);
167
+ common.logger.info(`Change detected in AppDefinition file.`);
321
168
  const startTime = /* @__PURE__ */ new Date();
322
169
  await runGenerators(
323
170
  await getAppDefinitionFromFile(args.schema),
324
171
  config.generators ?? []
325
172
  );
326
- dev.logger.success(
173
+ common.logger.success(
327
174
  `Generators completed in ${( new Date()).getTime() - startTime.getTime()}ms`
328
175
  );
329
176
  } catch (err) {
330
- dev.logger.error(err);
177
+ common.logger.error(err);
331
178
  }
332
179
  });
333
180
  }
334
181
  });
335
182
  async function getAppDefinitionFromFile(file) {
336
- if (!fs__default$1.existsSync(file)) {
183
+ if (!fs__default.existsSync(file)) {
337
184
  throw new Error(`Unable to find ${file}`);
338
185
  }
339
186
  const isTs = file.endsWith(".ts");
@@ -348,7 +195,7 @@ async function getAppDefinitionFromFile(file) {
348
195
  return schemaResult.config;
349
196
  } else {
350
197
  const parsingResult = JSON.parse(
351
- fs__default$1.readFileSync(file, { encoding: "utf-8" })
198
+ fs__default.readFileSync(file, { encoding: "utf-8" })
352
199
  );
353
200
  if (!codegenUtils.isAppDefinition(parsingResult)) {
354
201
  throw new Error(`Invalid App Definition at ${file}`);
@@ -357,7 +204,7 @@ async function getAppDefinitionFromFile(file) {
357
204
  }
358
205
  }
359
206
  async function runGenerators(def, generators) {
360
- dev.logger.info(`Generating ${generators?.length} client(s)`);
207
+ common.logger.info(`Generating ${generators?.length} client(s)`);
361
208
  await Promise.allSettled(
362
209
  generators.map(
363
210
  (gen) => gen.generator(
@@ -426,12 +273,12 @@ const init = citty.defineCommand({
426
273
  }
427
274
  }
428
275
  const dir = path__default.resolve(context.args.dir);
429
- if (!fs__default$1.existsSync(dir)) {
430
- fs__default$1.mkdirSync(dir);
276
+ if (!fs__default.existsSync(dir)) {
277
+ fs__default.mkdirSync(dir);
431
278
  }
432
- const dirFiles = fs__default$1.readdirSync(dir);
279
+ const dirFiles = fs__default.readdirSync(dir);
433
280
  if (dirFiles.length && !context.args.force) {
434
- dev.logger.error(
281
+ common.logger.error(
435
282
  `"${context.args.dir}" is a non-empty directory. To continue with this operation rerun "arri init" with the --force flag.`
436
283
  );
437
284
  process.exit(1);
@@ -444,7 +291,7 @@ const init = citty.defineCommand({
444
291
  await initPlugin(context.args.dir, context.args.force);
445
292
  break;
446
293
  default:
447
- dev.logger.error(`Unknown app type: '${type}'"`);
294
+ common.logger.error(`Unknown app type: '${type}'"`);
448
295
  break;
449
296
  }
450
297
  process.exit(0);
@@ -460,7 +307,7 @@ async function initApp(dir, force) {
460
307
  }
461
308
  ]);
462
309
  if (eslint) {
463
- dev.logger.warn(
310
+ common.logger.warn(
464
311
  `The Arri eslint starter uses the Eslint flat config syntax. If you are using VSCode you will need to enable "eslint.experimental.useFlatConfig" in your workspace settings. Please follow https://github.com/microsoft/vscode-eslint/issues/1644 for details.`
465
312
  );
466
313
  }
@@ -493,8 +340,8 @@ async function initApp(dir, force) {
493
340
  trailingComma: "all"
494
341
  })
495
342
  );
496
- dev.logger.success(`Project initialized in ${dir}!`);
497
- dev.logger.info(`To get started:
343
+ common.logger.success(`Project initialized in ${dir}!`);
344
+ common.logger.info(`To get started:
498
345
  - cd ${dir}
499
346
  - pnpm install
500
347
  - pnpm run dev`);
@@ -522,8 +369,8 @@ async function initPlugin(dir, force) {
522
369
  trailingComma: "all"
523
370
  })
524
371
  );
525
- dev.logger.success(`Project initialized in ${dir}!`);
526
- dev.logger.info(`To get started:
372
+ common.logger.success(`Project initialized in ${dir}!`);
373
+ common.logger.info(`To get started:
527
374
  - cd ${dir}
528
375
  - pnpm install`);
529
376
  }
@@ -541,12 +388,12 @@ const list = citty.defineCommand({
541
388
  }
542
389
  },
543
390
  async run({ args }) {
544
- const arriInfo = await dev.getArriPackageMetadata();
391
+ const arriInfo = await common.getArriPackageMetadata();
545
392
  if (args.tags) {
546
393
  const output2 = Object.keys(arriInfo["dist-tags"]).map(
547
394
  (tag) => `- ${tag} (${arriInfo["dist-tags"][tag]})`
548
395
  );
549
- dev.logger.log(output2.join("\n"));
396
+ common.logger.log(output2.join("\n"));
550
397
  return;
551
398
  }
552
399
  const tagMap = {};
@@ -561,7 +408,7 @@ const list = citty.defineCommand({
561
408
  }
562
409
  return `- ${version}`;
563
410
  });
564
- dev.logger.log(output.join("\n"));
411
+ common.logger.log(output.join("\n"));
565
412
  }
566
413
  });
567
414
 
@@ -578,7 +425,7 @@ const use = citty.defineCommand({
578
425
  }
579
426
  },
580
427
  async run({ args }) {
581
- const arriInfo = await dev.getArriPackageMetadata();
428
+ const arriInfo = await common.getArriPackageMetadata();
582
429
  const version = arriInfo["dist-tags"][args.version] ?? args.version;
583
430
  if (!arriInfo.versions[version]) {
584
431
  throw new Error(
@@ -886,7 +733,7 @@ const main = citty.defineCommand({
886
733
  subCommands: {
887
734
  build,
888
735
  codegen,
889
- dev: dev.dev,
736
+ dev: common.dev,
890
737
  init,
891
738
  list,
892
739
  use,