arri 0.2.3 → 0.3.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.
Files changed (3) hide show
  1. package/dist/cli.cjs +96 -23
  2. package/dist/cli.mjs +87 -17
  3. package/package.json +7 -5
package/dist/cli.cjs CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  const citty = require('citty');
5
5
  const node_child_process = require('node:child_process');
6
- const node_fs = require('node:fs');
7
- const fs = require('node:fs/promises');
6
+ const fs = require('node:fs');
7
+ const fs$1 = require('node:fs/promises');
8
8
  const arriCodegenUtils = require('arri-codegen-utils');
9
9
  const c12 = require('c12');
10
10
  const consola = require('consola');
@@ -18,6 +18,7 @@ const arriCodegenDart = require('arri-codegen-dart');
18
18
  const ofetch = require('ofetch');
19
19
  const chokidar = require('chokidar');
20
20
  const listhen = require('listhen');
21
+ const Degit = require('degit');
21
22
  require('arri-validate');
22
23
  require('h3');
23
24
 
@@ -35,19 +36,22 @@ function _interopNamespaceCompat(e) {
35
36
  return n;
36
37
  }
37
38
 
38
- const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
39
+ const fs__default$1 = /*#__PURE__*/_interopDefaultCompat(fs);
40
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs$1);
41
+ const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
39
42
  const esbuild__namespace = /*#__PURE__*/_interopNamespaceCompat(esbuild);
40
43
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
41
44
  const prettier__default = /*#__PURE__*/_interopDefaultCompat(prettier);
42
45
  const chokidar__default = /*#__PURE__*/_interopDefaultCompat(chokidar);
46
+ const Degit__default = /*#__PURE__*/_interopDefaultCompat(Degit);
43
47
 
44
48
  async function setupWorkingDir(config) {
45
49
  const arriDir = path__default.resolve(config.rootDir, config.buildDir);
46
50
  const outDir = path__default.resolve(config.rootDir, ".output");
47
- if (node_fs.existsSync(arriDir)) {
51
+ if (fs.existsSync(arriDir)) {
48
52
  await fs__default.rm(arriDir, { recursive: true, force: true });
49
53
  }
50
- if (node_fs.existsSync(outDir)) {
54
+ if (fs.existsSync(outDir)) {
51
55
  await fs__default.rm(outDir, { recursive: true, force: true });
52
56
  }
53
57
  await fs__default.mkdir(arriDir);
@@ -185,9 +189,9 @@ const build = citty.defineCommand({
185
189
  await startBuild(config$1, args.skipCodegen);
186
190
  }
187
191
  });
188
- const logger$1 = consola.createConsola().withTag("arri");
192
+ const logger$2 = consola.createConsola().withTag("arri");
189
193
  async function startBuild(config, skipCodeGen = false) {
190
- logger$1.log("Bundling server....");
194
+ logger$2.log("Bundling server....");
191
195
  await setupWorkingDir(config);
192
196
  await Promise.all([
193
197
  createRoutesModule(config),
@@ -196,30 +200,30 @@ async function startBuild(config, skipCodeGen = false) {
196
200
  ]);
197
201
  await transpileFiles(config);
198
202
  await bundleFiles(config);
199
- logger$1.log("Finished bundling");
203
+ logger$2.log("Finished bundling");
200
204
  const clientCount = config.clientGenerators.length;
201
205
  const codegenModule = path__default.resolve(config.rootDir, ".output", "codegen.js");
202
206
  if (clientCount > 0 && !skipCodeGen) {
203
- logger$1.log("Generating clients");
207
+ logger$2.log("Generating clients");
204
208
  node_child_process.execSync(`node ${codegenModule}`);
205
209
  const defJson = path__default.resolve(
206
210
  config.rootDir,
207
211
  ".output",
208
212
  "__definition.json"
209
213
  );
210
- const def = JSON.parse(node_fs.readFileSync(defJson, { encoding: "utf-8" }));
214
+ const def = JSON.parse(fs.readFileSync(defJson, { encoding: "utf-8" }));
211
215
  if (arriCodegenUtils.isAppDefinition(def)) {
212
216
  await Promise.all(
213
217
  config.clientGenerators.map((plugin) => plugin.generator(def))
214
218
  );
215
219
  }
216
- logger$1.log(`${clientCount} clients generated`);
220
+ logger$2.log(`${clientCount} clients generated`);
217
221
  } else {
218
- logger$1.log("No client generators specified. Skipping codegen.");
222
+ logger$2.log("No client generators specified. Skipping codegen.");
219
223
  }
220
- logger$1.log("Cleaning up files");
224
+ logger$2.log("Cleaning up files");
221
225
  await fs__default.rm(codegenModule);
222
- logger$1.log(
226
+ logger$2.log(
223
227
  `Build finished! You can start your server by running "node .output/server.js"`
224
228
  );
225
229
  }
@@ -354,11 +358,11 @@ const codegenDart = citty.defineCommand({
354
358
  const result = await ofetch.ofetch(args.location);
355
359
  def = result;
356
360
  } else {
357
- if (!node_fs.existsSync(args.location)) {
361
+ if (!fs.existsSync(args.location)) {
358
362
  throw new Error(`Unable to find ${args.location}`);
359
363
  }
360
364
  const jsonString = JSON.parse(
361
- node_fs.readFileSync(args.location, { encoding: "utf-8" })
365
+ fs.readFileSync(args.location, { encoding: "utf-8" })
362
366
  );
363
367
  def = jsonString;
364
368
  }
@@ -401,7 +405,7 @@ const codegen = citty.defineCommand({
401
405
  }
402
406
  });
403
407
 
404
- const logger = consola.createConsola().withTag("arri");
408
+ const logger$1 = consola.createConsola().withTag("arri");
405
409
  const dev = citty.defineCommand({
406
410
  meta: {
407
411
  name: "dev",
@@ -429,7 +433,7 @@ const dev = citty.defineCommand({
429
433
  const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", "server.js"), {
430
434
  public: true,
431
435
  port: config.port,
432
- logger,
436
+ logger: logger$1,
433
437
  qr: showQr
434
438
  });
435
439
  async function bundleFilesContext(config) {
@@ -492,14 +496,14 @@ async function startDevServer(config) {
492
496
  await createRoutesModule(config);
493
497
  let bundleCreated = false;
494
498
  try {
495
- logger.log(
499
+ logger$1.log(
496
500
  "Change detected. Bundling files and restarting server...."
497
501
  );
498
502
  await transpileFiles(config);
499
503
  await bundleFiles.rebuild();
500
504
  bundleCreated = true;
501
505
  } catch (err) {
502
- logger.error("ERROR", err);
506
+ logger$1.error("ERROR", err);
503
507
  bundleCreated = false;
504
508
  }
505
509
  if (bundleCreated && config.clientGenerators.length) {
@@ -522,14 +526,14 @@ async function generateClients(config$1) {
522
526
  if (!arriCodegenUtils.isAppDefinition(result)) {
523
527
  return;
524
528
  }
525
- logger.log(`Generating client code...`);
529
+ logger$1.log(`Generating client code...`);
526
530
  const clientCount = config$1.clientGenerators.length;
527
531
  await Promise.all(
528
532
  config$1.clientGenerators.map(
529
533
  (generator) => generator.generator(result)
530
534
  )
531
535
  );
532
- logger.log(
536
+ logger$1.log(
533
537
  `Generated ${clientCount} client${clientCount === 1 ? "" : "s"}`
534
538
  );
535
539
  } catch (err) {
@@ -564,11 +568,80 @@ export default app.h3App;`;
564
568
  );
565
569
  }
566
570
 
571
+ const logger = consola.createConsola();
572
+ const init = citty.defineCommand({
573
+ meta: {
574
+ name: "Init",
575
+ description: "Scaffold an Arri app"
576
+ },
577
+ args: {
578
+ dir: {
579
+ type: "positional",
580
+ required: true,
581
+ description: "Directory where to initialize the project"
582
+ },
583
+ force: {
584
+ type: "boolean",
585
+ default: false,
586
+ alias: "f",
587
+ description: "Force created a project when if a directory already exists"
588
+ }
589
+ },
590
+ async run(context) {
591
+ const dir = path__default.resolve(context.args.dir);
592
+ if (!fs__default$1.existsSync(dir)) {
593
+ fs__default$1.mkdirSync(dir);
594
+ }
595
+ const dirFiles = fs__default$1.readdirSync(dir);
596
+ if (dirFiles.length && !context.args.force) {
597
+ logger.error(
598
+ `"${context.args.dir}" is a non-empty directory. To continue with this operation rerun "arri init" with the --force flag.`
599
+ );
600
+ process.exit(1);
601
+ }
602
+ const degit = Degit__default("https://github.com/modiimedia/arri-starters", {
603
+ force: context.args.force
604
+ });
605
+ await degit.clone(dir);
606
+ fs.rmSync(path__default.resolve(dir, "pnpm-lock.yaml"));
607
+ const packageJson = JSON.parse(
608
+ fs.readFileSync(path__default.resolve(dir, "package.json"), {
609
+ encoding: "utf-8"
610
+ })
611
+ );
612
+ packageJson.name = scule.kebabCase(context.args.dir);
613
+ packageJson.description = "An RPC server created with Arri RPC";
614
+ packageJson.private = true;
615
+ delete packageJson.license;
616
+ delete packageJson.main;
617
+ delete packageJson.author;
618
+ delete packageJson.tags;
619
+ fs.writeFileSync(
620
+ path__default.resolve(dir, "package.json"),
621
+ await prettier__default.format(JSON.stringify(packageJson), {
622
+ parser: "json",
623
+ tabWidth: 4,
624
+ semi: true,
625
+ endOfLine: "lf",
626
+ trailingComma: "all"
627
+ })
628
+ );
629
+ consola__default.log(
630
+ `Project initialized in ${context.args.dir}. To get started:
631
+ cd ${context.args.dir}
632
+ npm install
633
+ npm run dev`
634
+ );
635
+ process.exit(0);
636
+ }
637
+ });
638
+
567
639
  const main = citty.defineCommand({
568
640
  subCommands: {
569
641
  build,
570
642
  dev,
571
- codegen
643
+ codegen,
644
+ init
572
645
  }
573
646
  });
574
647
  void citty.runMain(main);
package/dist/cli.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #! /usr/bin/env node
2
2
  import { defineCommand, runMain } from 'citty';
3
3
  import { execSync } from 'node:child_process';
4
- import { existsSync, readFileSync } from 'node:fs';
4
+ import fs$1, { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
5
5
  import fs from 'node:fs/promises';
6
6
  import { removeDisallowedChars, isAppDefinition } from 'arri-codegen-utils';
7
7
  import { loadConfig } from 'c12';
8
- import { createConsola } from 'consola';
8
+ import consola, { createConsola } from 'consola';
9
9
  import * as esbuild from 'esbuild';
10
10
  import { build as build$1 } from 'esbuild';
11
11
  import path from 'pathe';
@@ -17,6 +17,7 @@ import { dartClientGenerator } from 'arri-codegen-dart';
17
17
  import { ofetch } from 'ofetch';
18
18
  import chokidar from 'chokidar';
19
19
  import { listenAndWatch } from 'listhen';
20
+ import Degit from 'degit';
20
21
  import 'arri-validate';
21
22
  import 'h3';
22
23
 
@@ -164,9 +165,9 @@ const build = defineCommand({
164
165
  await startBuild(config, args.skipCodegen);
165
166
  }
166
167
  });
167
- const logger$1 = createConsola().withTag("arri");
168
+ const logger$2 = createConsola().withTag("arri");
168
169
  async function startBuild(config, skipCodeGen = false) {
169
- logger$1.log("Bundling server....");
170
+ logger$2.log("Bundling server....");
170
171
  await setupWorkingDir(config);
171
172
  await Promise.all([
172
173
  createRoutesModule(config),
@@ -175,11 +176,11 @@ async function startBuild(config, skipCodeGen = false) {
175
176
  ]);
176
177
  await transpileFiles(config);
177
178
  await bundleFiles(config);
178
- logger$1.log("Finished bundling");
179
+ logger$2.log("Finished bundling");
179
180
  const clientCount = config.clientGenerators.length;
180
181
  const codegenModule = path.resolve(config.rootDir, ".output", "codegen.js");
181
182
  if (clientCount > 0 && !skipCodeGen) {
182
- logger$1.log("Generating clients");
183
+ logger$2.log("Generating clients");
183
184
  execSync(`node ${codegenModule}`);
184
185
  const defJson = path.resolve(
185
186
  config.rootDir,
@@ -192,13 +193,13 @@ async function startBuild(config, skipCodeGen = false) {
192
193
  config.clientGenerators.map((plugin) => plugin.generator(def))
193
194
  );
194
195
  }
195
- logger$1.log(`${clientCount} clients generated`);
196
+ logger$2.log(`${clientCount} clients generated`);
196
197
  } else {
197
- logger$1.log("No client generators specified. Skipping codegen.");
198
+ logger$2.log("No client generators specified. Skipping codegen.");
198
199
  }
199
- logger$1.log("Cleaning up files");
200
+ logger$2.log("Cleaning up files");
200
201
  await fs.rm(codegenModule);
201
- logger$1.log(
202
+ logger$2.log(
202
203
  `Build finished! You can start your server by running "node .output/server.js"`
203
204
  );
204
205
  }
@@ -380,7 +381,7 @@ const codegen = defineCommand({
380
381
  }
381
382
  });
382
383
 
383
- const logger = createConsola().withTag("arri");
384
+ const logger$1 = createConsola().withTag("arri");
384
385
  const dev = defineCommand({
385
386
  meta: {
386
387
  name: "dev",
@@ -408,7 +409,7 @@ const dev = defineCommand({
408
409
  const startListener = (config, showQr = false) => listenAndWatch(path.resolve(config.rootDir, ".output", "server.js"), {
409
410
  public: true,
410
411
  port: config.port,
411
- logger,
412
+ logger: logger$1,
412
413
  qr: showQr
413
414
  });
414
415
  async function bundleFilesContext(config) {
@@ -471,14 +472,14 @@ async function startDevServer(config) {
471
472
  await createRoutesModule(config);
472
473
  let bundleCreated = false;
473
474
  try {
474
- logger.log(
475
+ logger$1.log(
475
476
  "Change detected. Bundling files and restarting server...."
476
477
  );
477
478
  await transpileFiles(config);
478
479
  await bundleFiles.rebuild();
479
480
  bundleCreated = true;
480
481
  } catch (err) {
481
- logger.error("ERROR", err);
482
+ logger$1.error("ERROR", err);
482
483
  bundleCreated = false;
483
484
  }
484
485
  if (bundleCreated && config.clientGenerators.length) {
@@ -501,14 +502,14 @@ async function generateClients(config) {
501
502
  if (!isAppDefinition(result)) {
502
503
  return;
503
504
  }
504
- logger.log(`Generating client code...`);
505
+ logger$1.log(`Generating client code...`);
505
506
  const clientCount = config.clientGenerators.length;
506
507
  await Promise.all(
507
508
  config.clientGenerators.map(
508
509
  (generator) => generator.generator(result)
509
510
  )
510
511
  );
511
- logger.log(
512
+ logger$1.log(
512
513
  `Generated ${clientCount} client${clientCount === 1 ? "" : "s"}`
513
514
  );
514
515
  } catch (err) {
@@ -543,11 +544,80 @@ export default app.h3App;`;
543
544
  );
544
545
  }
545
546
 
547
+ const logger = createConsola();
548
+ const init = defineCommand({
549
+ meta: {
550
+ name: "Init",
551
+ description: "Scaffold an Arri app"
552
+ },
553
+ args: {
554
+ dir: {
555
+ type: "positional",
556
+ required: true,
557
+ description: "Directory where to initialize the project"
558
+ },
559
+ force: {
560
+ type: "boolean",
561
+ default: false,
562
+ alias: "f",
563
+ description: "Force created a project when if a directory already exists"
564
+ }
565
+ },
566
+ async run(context) {
567
+ const dir = path.resolve(context.args.dir);
568
+ if (!fs$1.existsSync(dir)) {
569
+ fs$1.mkdirSync(dir);
570
+ }
571
+ const dirFiles = fs$1.readdirSync(dir);
572
+ if (dirFiles.length && !context.args.force) {
573
+ logger.error(
574
+ `"${context.args.dir}" is a non-empty directory. To continue with this operation rerun "arri init" with the --force flag.`
575
+ );
576
+ process.exit(1);
577
+ }
578
+ const degit = Degit("https://github.com/modiimedia/arri-starters", {
579
+ force: context.args.force
580
+ });
581
+ await degit.clone(dir);
582
+ rmSync(path.resolve(dir, "pnpm-lock.yaml"));
583
+ const packageJson = JSON.parse(
584
+ readFileSync(path.resolve(dir, "package.json"), {
585
+ encoding: "utf-8"
586
+ })
587
+ );
588
+ packageJson.name = kebabCase(context.args.dir);
589
+ packageJson.description = "An RPC server created with Arri RPC";
590
+ packageJson.private = true;
591
+ delete packageJson.license;
592
+ delete packageJson.main;
593
+ delete packageJson.author;
594
+ delete packageJson.tags;
595
+ writeFileSync(
596
+ path.resolve(dir, "package.json"),
597
+ await prettier.format(JSON.stringify(packageJson), {
598
+ parser: "json",
599
+ tabWidth: 4,
600
+ semi: true,
601
+ endOfLine: "lf",
602
+ trailingComma: "all"
603
+ })
604
+ );
605
+ consola.log(
606
+ `Project initialized in ${context.args.dir}. To get started:
607
+ cd ${context.args.dir}
608
+ npm install
609
+ npm run dev`
610
+ );
611
+ process.exit(0);
612
+ }
613
+ });
614
+
546
615
  const main = defineCommand({
547
616
  subCommands: {
548
617
  build,
549
618
  dev,
550
- codegen
619
+ codegen,
620
+ init
551
621
  }
552
622
  });
553
623
  void runMain(main);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -21,6 +21,7 @@
21
21
  "chokidar": "^3.5.3",
22
22
  "citty": "^0.1.4",
23
23
  "consola": "^3.2.3",
24
+ "degit": "^2.8.4",
24
25
  "esbuild": "^0.19.5",
25
26
  "globby": "^13.2.2",
26
27
  "h3": "^1.8.2",
@@ -29,15 +30,16 @@
29
30
  "pathe": "^1.1.1",
30
31
  "prettier": "^3.0.3",
31
32
  "scule": "^1.0.0",
32
- "arri-codegen-ts": "0.2.3",
33
- "arri-codegen-dart": "0.2.3",
34
- "arri-codegen-utils": "0.2.3",
35
- "arri-validate": "0.2.3"
33
+ "arri-codegen-ts": "0.3.0",
34
+ "arri-validate": "0.3.0",
35
+ "arri-codegen-utils": "0.3.0",
36
+ "arri-codegen-dart": "0.3.0"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "listhen": "1.x"
39
40
  },
40
41
  "devDependencies": {
42
+ "@types/degit": "^2.8.5",
41
43
  "bun-types": "^1.0.7"
42
44
  }
43
45
  }