@mojojs/core 1.26.18 → 2.0.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 (156) hide show
  1. package/README.md +1 -1
  2. package/lib/app.d.ts +31 -16
  3. package/lib/app.js +181 -126
  4. package/lib/body/params.js +0 -1
  5. package/lib/body.d.ts +13 -5
  6. package/lib/body.js +47 -17
  7. package/lib/cache.d.ts +1 -2
  8. package/lib/cache.js +12 -21
  9. package/lib/cgi.d.ts +3 -3
  10. package/lib/cgi.js +16 -8
  11. package/lib/cli/cgi.d.ts +1 -1
  12. package/lib/cli/cgi.js +1 -2
  13. package/lib/cli/create-full-app.d.ts +1 -1
  14. package/lib/cli/create-full-app.js +27 -27
  15. package/lib/cli/create-lite-app.d.ts +1 -1
  16. package/lib/cli/create-lite-app.js +2 -3
  17. package/lib/cli/create-plugin.d.ts +1 -1
  18. package/lib/cli/create-plugin.js +25 -23
  19. package/lib/cli/eval.d.ts +1 -1
  20. package/lib/cli/eval.js +12 -5
  21. package/lib/cli/get.d.ts +1 -1
  22. package/lib/cli/get.js +30 -26
  23. package/lib/cli/repl.d.ts +1 -1
  24. package/lib/cli/repl.js +0 -1
  25. package/lib/cli/routes.d.ts +1 -1
  26. package/lib/cli/routes.js +10 -7
  27. package/lib/cli/server.d.ts +1 -1
  28. package/lib/cli/server.js +41 -24
  29. package/lib/cli/version.js +1 -2
  30. package/lib/cli.d.ts +1 -1
  31. package/lib/cli.js +25 -19
  32. package/lib/context.d.ts +33 -10
  33. package/lib/context.js +137 -32
  34. package/lib/core.d.ts +14 -13
  35. package/lib/core.js +12 -12
  36. package/lib/headers.js +5 -4
  37. package/lib/hooks.d.ts +1 -1
  38. package/lib/hooks.js +1 -5
  39. package/lib/logger.d.ts +2 -2
  40. package/lib/logger.js +28 -16
  41. package/lib/mime.js +10 -13
  42. package/lib/plugins/default-conditions.d.ts +1 -1
  43. package/lib/plugins/default-conditions.js +0 -1
  44. package/lib/plugins/default-helpers.d.ts +1 -1
  45. package/lib/plugins/default-helpers.js +28 -11
  46. package/lib/plugins/json-config.d.ts +1 -1
  47. package/lib/plugins/json-config.js +0 -1
  48. package/lib/plugins/mount.d.ts +1 -1
  49. package/lib/plugins/mount.js +0 -1
  50. package/lib/plugins/tmpl-engine.d.ts +1 -1
  51. package/lib/plugins/tmpl-engine.js +2 -5
  52. package/lib/plugins/yaml-config.d.ts +1 -1
  53. package/lib/plugins/yaml-config.js +1 -2
  54. package/lib/renderer.d.ts +1 -1
  55. package/lib/renderer.js +27 -30
  56. package/lib/router/pattern.d.ts +1 -1
  57. package/lib/router/pattern.js +25 -14
  58. package/lib/router/plan.d.ts +1 -1
  59. package/lib/router/plan.js +12 -15
  60. package/lib/router/route.d.ts +10 -3
  61. package/lib/router/route.js +44 -38
  62. package/lib/router.d.ts +4 -4
  63. package/lib/router.js +25 -26
  64. package/lib/server/cookie.d.ts +1 -1
  65. package/lib/server/cookie.js +3 -2
  66. package/lib/server/request.d.ts +3 -3
  67. package/lib/server/request.js +44 -17
  68. package/lib/server/response.d.ts +3 -3
  69. package/lib/server/response.js +20 -20
  70. package/lib/server.d.ts +7 -2
  71. package/lib/server.js +70 -20
  72. package/lib/session.d.ts +8 -3
  73. package/lib/session.js +47 -29
  74. package/lib/sse.d.ts +10 -0
  75. package/lib/sse.js +62 -0
  76. package/lib/static.d.ts +1 -1
  77. package/lib/static.js +27 -22
  78. package/lib/types.d.ts +13 -5
  79. package/lib/types.js +0 -1
  80. package/lib/user-agent/cookie-jar.d.ts +2 -2
  81. package/lib/user-agent/cookie-jar.js +6 -9
  82. package/lib/user-agent/mock.d.ts +4 -4
  83. package/lib/user-agent/mock.js +6 -7
  84. package/lib/user-agent/response.d.ts +12 -1
  85. package/lib/user-agent/response.js +36 -2
  86. package/lib/user-agent/test.d.ts +75 -5
  87. package/lib/user-agent/test.js +147 -13
  88. package/lib/user-agent/transport/http.d.ts +2 -2
  89. package/lib/user-agent/transport/http.js +7 -10
  90. package/lib/user-agent/transport/https.d.ts +2 -2
  91. package/lib/user-agent/transport/https.js +2 -6
  92. package/lib/user-agent/transport/ws.d.ts +2 -2
  93. package/lib/user-agent/transport/ws.js +2 -3
  94. package/lib/user-agent.d.ts +21 -18
  95. package/lib/user-agent.js +70 -49
  96. package/lib/util.d.ts +13 -0
  97. package/lib/util.js +35 -11
  98. package/lib/validator/result.d.ts +1 -1
  99. package/lib/validator/result.js +8 -1
  100. package/lib/validator.d.ts +2 -2
  101. package/lib/validator.js +3 -6
  102. package/lib/websocket.d.ts +2 -2
  103. package/lib/websocket.js +9 -1
  104. package/package.json +22 -29
  105. package/lib/app.js.map +0 -1
  106. package/lib/body/params.js.map +0 -1
  107. package/lib/body.js.map +0 -1
  108. package/lib/cache.js.map +0 -1
  109. package/lib/cgi.js.map +0 -1
  110. package/lib/cli/cgi.js.map +0 -1
  111. package/lib/cli/create-full-app.js.map +0 -1
  112. package/lib/cli/create-lite-app.js.map +0 -1
  113. package/lib/cli/create-plugin.js.map +0 -1
  114. package/lib/cli/eval.js.map +0 -1
  115. package/lib/cli/get.js.map +0 -1
  116. package/lib/cli/repl.js.map +0 -1
  117. package/lib/cli/routes.js.map +0 -1
  118. package/lib/cli/server.js.map +0 -1
  119. package/lib/cli/version.js.map +0 -1
  120. package/lib/cli.js.map +0 -1
  121. package/lib/context.js.map +0 -1
  122. package/lib/core.js.map +0 -1
  123. package/lib/headers.js.map +0 -1
  124. package/lib/hooks.js.map +0 -1
  125. package/lib/logger.js.map +0 -1
  126. package/lib/mime.js.map +0 -1
  127. package/lib/plugins/default-conditions.js.map +0 -1
  128. package/lib/plugins/default-helpers.js.map +0 -1
  129. package/lib/plugins/json-config.js.map +0 -1
  130. package/lib/plugins/mount.js.map +0 -1
  131. package/lib/plugins/tmpl-engine.js.map +0 -1
  132. package/lib/plugins/yaml-config.js.map +0 -1
  133. package/lib/renderer.js.map +0 -1
  134. package/lib/router/pattern.js.map +0 -1
  135. package/lib/router/plan.js.map +0 -1
  136. package/lib/router/route.js.map +0 -1
  137. package/lib/router.js.map +0 -1
  138. package/lib/server/cookie.js.map +0 -1
  139. package/lib/server/request.js.map +0 -1
  140. package/lib/server/response.js.map +0 -1
  141. package/lib/server.js.map +0 -1
  142. package/lib/session.js.map +0 -1
  143. package/lib/static.js.map +0 -1
  144. package/lib/types.js.map +0 -1
  145. package/lib/user-agent/cookie-jar.js.map +0 -1
  146. package/lib/user-agent/mock.js.map +0 -1
  147. package/lib/user-agent/response.js.map +0 -1
  148. package/lib/user-agent/test.js.map +0 -1
  149. package/lib/user-agent/transport/http.js.map +0 -1
  150. package/lib/user-agent/transport/https.js.map +0 -1
  151. package/lib/user-agent/transport/ws.js.map +0 -1
  152. package/lib/user-agent.js.map +0 -1
  153. package/lib/util.js.map +0 -1
  154. package/lib/validator/result.js.map +0 -1
  155. package/lib/validator.js.map +0 -1
  156. package/lib/websocket.js.map +0 -1
package/lib/cli/cgi.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * CGI command.
4
4
  */
package/lib/cli/cgi.js CHANGED
@@ -1,4 +1,4 @@
1
- import { CGI } from '../cgi.js';
1
+ import { CGI } from "../cgi.js";
2
2
  /**
3
3
  * CGI command.
4
4
  */
@@ -13,4 +13,3 @@ cgiCommand.usage = `Usage: APPLICATION cgi [OPTIONS]
13
13
  Options:
14
14
  -h, --help Show this summary of available options
15
15
  `;
16
- //# sourceMappingURL=cgi.js.map
@@ -1,4 +1,4 @@
1
- import type { App } from '../app.js';
1
+ import type { App } from '../app.ts';
2
2
  /**
3
3
  * Minimal application generator command.
4
4
  */
@@ -1,13 +1,18 @@
1
1
  import crypto from 'node:crypto';
2
- import { version } from '../core.js';
3
- import * as util from '../util.js';
4
- import nopt from 'nopt';
2
+ import { parseArgs } from 'node:util';
3
+ import { version } from "../core.js";
4
+ import * as util from "../util.js";
5
5
  /**
6
6
  * Minimal application generator command.
7
7
  */
8
8
  export default async function createFullAppCommand(app, args) {
9
- const parsed = nopt({ ts: Boolean }, {}, args, 1);
10
- const ts = parsed.ts === true;
9
+ const { values } = parseArgs({
10
+ args: args.slice(1),
11
+ options: { ts: { type: 'boolean' } },
12
+ allowPositionals: true,
13
+ allowNegative: true
14
+ });
15
+ const ts = values.ts === true;
11
16
  process.stdout.write('Generating application directory structure:\n');
12
17
  await util.cliCreateFile('config.yml', yamlConfig, { secret: crypto.randomBytes(16).toString('hex') });
13
18
  await util.cliCreateDir('views/layouts');
@@ -24,35 +29,31 @@ export default async function createFullAppCommand(app, args) {
24
29
  await util.cliCreateFile('src/controllers/example.ts', tsController);
25
30
  await util.cliCreateDir('src/models');
26
31
  await util.cliCreateDir('test');
27
- await util.cliCreateFile('test/example.js', jsTest, { indexPath: '../lib/index.js' });
32
+ await util.cliCreateFile('test/example.js', jsTest, { indexPath: '../src/index.ts' });
33
+ // Node.js runs the TypeScript sources directly, so tsc is only used for type checking
28
34
  const tsConfig = {
29
35
  compilerOptions: {
30
- lib: ['ESNext', 'DOM'],
31
- target: 'ES2020',
32
- module: 'ES2020',
33
- sourceMap: true,
34
- declaration: true,
35
- incremental: true,
36
- moduleResolution: 'node',
37
- esModuleInterop: true,
36
+ lib: ['ESNext'],
37
+ target: 'ESNext',
38
+ module: 'nodenext',
39
+ moduleResolution: 'nodenext',
40
+ noEmit: true,
41
+ allowImportingTsExtensions: true,
42
+ erasableSyntaxOnly: true,
43
+ verbatimModuleSyntax: true,
38
44
  noErrorTruncation: true,
39
- strict: true,
40
- outDir: 'lib',
41
- rootDir: 'src',
42
- composite: true
45
+ strict: true
43
46
  },
44
47
  include: ['src/**/*']
45
48
  };
46
49
  await util.cliCreateFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
47
50
  await util.cliFixPackage({
48
51
  dependencies: { '@mojojs/core': `^${version}` },
49
- devDependencies: await util.devDependencies(/^(@types\/.+|nodemon|tap|typescript)$/),
52
+ devDependencies: await util.devDependencies(/^(@types\/node|tap|typescript)$/),
50
53
  scripts: {
51
- build: 'npx tsc --build ./',
52
- 'build:test': 'npm run build && npm test',
53
- 'build:watch': 'npm run build -- --watch',
54
- dev: 'npx nodemon lib/index.js server',
55
- start: 'NODE_ENV=production node lib/index.js server -l http://*:8080',
54
+ check: 'npx tsc',
55
+ dev: 'node --watch src/index.ts server',
56
+ start: 'NODE_ENV=production node src/index.ts server -l http://*:8080',
56
57
  test: 'node --test test/*.js'
57
58
  }
58
59
  });
@@ -67,9 +68,9 @@ export default async function createFullAppCommand(app, args) {
67
68
  await util.cliCreateFile('test/example.js', jsTest, { indexPath: '../index.js' });
68
69
  await util.cliFixPackage({
69
70
  dependencies: { '@mojojs/core': `^${version}` },
70
- devDependencies: await util.devDependencies(/^(nodemon|tap)$/),
71
+ devDependencies: await util.devDependencies(/^tap$/),
71
72
  scripts: {
72
- dev: 'npx nodemon index.js server',
73
+ dev: 'node --watch index.js server',
73
74
  start: 'NODE_ENV=production node index.js server -l http://*:8080',
74
75
  test: 'node --test test/*.js'
75
76
  }
@@ -163,4 +164,3 @@ t.test('Example application', async t => {
163
164
  await ua.stop();
164
165
  });
165
166
  `;
166
- //# sourceMappingURL=create-full-app.js.map
@@ -1,4 +1,4 @@
1
- import type { App } from '../app.js';
1
+ import type { App } from '../app.ts';
2
2
  /**
3
3
  * Application generator command.
4
4
  */
@@ -1,5 +1,5 @@
1
- import { version } from '../core.js';
2
- import * as util from '../util.js';
1
+ import { version } from "../core.js";
2
+ import * as util from "../util.js";
3
3
  /**
4
4
  * Application generator command.
5
5
  */
@@ -60,4 +60,3 @@ const defaultLayout = \`
60
60
  </html>
61
61
  \`;
62
62
  `;
63
- //# sourceMappingURL=create-lite-app.js.map
@@ -1,4 +1,4 @@
1
- import type { App } from '../app.js';
1
+ import type { App } from '../app.ts';
2
2
  /**
3
3
  * Plugin generator command.
4
4
  */
@@ -1,24 +1,30 @@
1
- import { version } from '../core.js';
2
- import * as util from '../util.js';
3
- import nopt from 'nopt';
1
+ import { parseArgs } from 'node:util';
2
+ import { version } from "../core.js";
3
+ import * as util from "../util.js";
4
4
  /**
5
5
  * Plugin generator command.
6
6
  */
7
7
  export default async function createPluginCommand(app, args) {
8
- const parsed = nopt({ ts: Boolean }, {}, args, 1);
9
- const ts = parsed.ts === true;
8
+ const { values, positionals } = parseArgs({
9
+ args: args.slice(1),
10
+ options: { ts: { type: 'boolean' } },
11
+ allowPositionals: true,
12
+ allowNegative: true
13
+ });
14
+ const ts = values.ts === true;
10
15
  const stdout = process.stdout;
11
16
  stdout.write('Generating plugin:\n');
12
- const name = parsed.argv.remain[0] ?? 'mojo-plugin-myplugin';
17
+ const name = positionals[0] ?? 'mojo-plugin-myplugin';
13
18
  const file = `lib/${name}.js`;
19
+ const tsFile = `src/${name}.ts`;
14
20
  await util.cliCreateDir('test');
15
- await util.cliCreateFile('test/basic.js', test, { file });
21
+ await util.cliCreateFile('test/basic.js', test, { file: ts === true ? tsFile : file });
16
22
  await util.cliCreateFile('README.md', readme, { name });
17
23
  const commonSettings = {
18
24
  author: 'A Good Programmer <nospam@example.com>',
19
25
  description: 'A mojo.js plugin',
20
26
  dependencies: { '@mojojs/core': `^${version}` },
21
- exports: './lib/plugin.js',
27
+ exports: `./${file}`,
22
28
  files: ['lib/'],
23
29
  name,
24
30
  license: 'MIT',
@@ -26,35 +32,32 @@ export default async function createPluginCommand(app, args) {
26
32
  };
27
33
  // TypeScript
28
34
  if (ts === true) {
29
- const tsFile = `src/${name}.ts`;
30
35
  await util.cliCreateDir('src');
31
36
  await util.cliCreateFile(tsFile, tsPlugin);
32
37
  const tsConfig = {
33
38
  compilerOptions: {
34
- lib: ['ESNext', 'DOM'],
35
- target: 'ES2020',
36
- module: 'ES2020',
37
- sourceMap: true,
39
+ lib: ['ESNext'],
40
+ target: 'ES2023',
41
+ module: 'nodenext',
42
+ moduleResolution: 'nodenext',
38
43
  declaration: true,
39
- incremental: true,
40
- moduleResolution: 'node',
41
- esModuleInterop: true,
44
+ erasableSyntaxOnly: true,
45
+ verbatimModuleSyntax: true,
46
+ rewriteRelativeImportExtensions: true,
42
47
  noErrorTruncation: true,
43
48
  strict: true,
44
49
  outDir: 'lib',
45
- rootDir: 'src',
46
- composite: true
50
+ rootDir: 'src'
47
51
  },
48
52
  include: ['src/**/*']
49
53
  };
50
54
  await util.cliCreateFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
51
55
  await util.cliFixPackage({
52
56
  ...commonSettings,
53
- devDependencies: await util.devDependencies(/^(@types\/.+|tap|typescript)$/),
57
+ devDependencies: await util.devDependencies(/^(@types\/node|tap|typescript)$/),
54
58
  scripts: {
55
- build: 'npx tsc --build ./',
56
- 'build:test': 'npm run build && npm test',
57
- 'build:watch': 'npm run build -- --watch',
59
+ build: 'npx tsc',
60
+ prepublishOnly: 'npm run build',
58
61
  test: 'node --test test/*.js'
59
62
  }
60
63
  });
@@ -137,4 +140,3 @@ All you need is Node.js 16.0.0 (or newer).
137
140
  $ npm install <%= name %>
138
141
  \`\`\`
139
142
  `;
140
- //# sourceMappingURL=create-plugin.js.map
package/lib/cli/eval.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * Eval command.
4
4
  */
package/lib/cli/eval.js CHANGED
@@ -1,11 +1,16 @@
1
- import nopt from 'nopt';
1
+ import { parseArgs } from 'node:util';
2
2
  /**
3
3
  * Eval command.
4
4
  */
5
5
  export default async function evalCommand(app, args) {
6
- const parsed = nopt({ verbose: Boolean }, { v: '--verbose' }, args, 1);
7
- const output = await eval('(async () => (' + parsed.argv.remain[0] + '))()');
8
- if (parsed.verbose === true)
6
+ const { values, positionals } = parseArgs({
7
+ args: args.slice(1),
8
+ options: { verbose: { type: 'boolean', short: 'v' } },
9
+ allowPositionals: true,
10
+ allowNegative: true
11
+ });
12
+ const output = await eval('(async () => (' + positionals[0] + '))()');
13
+ if (values.verbose === true)
9
14
  console.log(output);
10
15
  }
11
16
  evalCommand.description = 'Run code against application';
@@ -15,8 +20,10 @@ evalCommand.usage = `Usage: APPLICATION eval [OPTIONS] CODE
15
20
  node index.js eval -v 'app.home.toString()'
16
21
  node index.js eval -v 'app.renderer.viewPaths'
17
22
 
23
+ # Use "--" for code starting with "-"
24
+ node index.js eval -v -- '-1 + 2'
25
+
18
26
  Options:
19
27
  -h, --help Show this summary of available options
20
28
  -v, --verbose Print return value to stdout
21
29
  `;
22
- //# sourceMappingURL=eval.js.map
package/lib/cli/get.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * Get command.
4
4
  */
package/lib/cli/get.js CHANGED
@@ -1,41 +1,46 @@
1
- import chalk from 'chalk';
2
- import nopt from 'nopt';
1
+ import { parseArgs, styleText } from 'node:util';
3
2
  /**
4
3
  * Get command.
5
4
  */
6
5
  export default async function getCommand(app, args) {
7
- const parsed = nopt({
8
- body: String,
9
- header: [String, Array],
10
- insecure: Boolean,
11
- method: String,
12
- redirect: Boolean,
13
- 'socket-path': String,
14
- verbose: Boolean
15
- }, { b: '--body', H: '--header', k: '--insecure', X: '--method', P: '--socket-path', r: '--redirect', v: '--verbose' }, args, 1);
16
- const argv = parsed.argv;
6
+ const { values, positionals } = parseArgs({
7
+ args: args.slice(1),
8
+ options: {
9
+ body: { type: 'string', short: 'b' },
10
+ header: { type: 'string', short: 'H', multiple: true },
11
+ insecure: { type: 'boolean', short: 'k' },
12
+ method: { type: 'string', short: 'X' },
13
+ redirect: { type: 'boolean', short: 'r' },
14
+ 'socket-path': { type: 'string', short: 'P' },
15
+ verbose: { type: 'boolean', short: 'v' }
16
+ },
17
+ allowPositionals: true,
18
+ allowNegative: true
19
+ });
17
20
  const request = {
18
- body: parsed.body,
19
- headers: parseHeaders(parsed.header),
20
- insecure: parsed.insecure,
21
- method: parsed.method ?? 'GET',
22
- socketPath: parsed['socket-path'],
23
- url: argv.remain[0] ?? '/'
21
+ body: values.body,
22
+ headers: parseHeaders(values.header),
23
+ insecure: values.insecure,
24
+ method: values.method ?? 'GET',
25
+ socketPath: values['socket-path'],
26
+ url: positionals[0] ?? '/'
24
27
  };
25
- const ua = await app.newMockUserAgent({ maxRedirects: parsed.redirect === true ? 10 : 0 });
28
+ const ua = await app.newMockUserAgent({ maxRedirects: values.redirect === true ? 10 : 0 });
26
29
  const res = await ua.request(request);
27
- if (parsed.verbose === true) {
30
+ if (values.verbose === true) {
28
31
  const stderr = process.stderr;
29
- const resVersion = chalk.blue('HTTP') + '/' + chalk.blue(res.httpVersion);
32
+ // Colors depend on the stream the output goes to
33
+ const options = { stream: stderr };
34
+ const resVersion = styleText('blue', 'HTTP', options) + '/' + styleText('blue', res.httpVersion, options);
30
35
  const statusCode = res.statusCode;
31
- const statusMessage = chalk.blue(res.statusMessage);
36
+ const statusMessage = styleText('blue', res.statusMessage, options);
32
37
  stderr.write(`${resVersion} ${statusCode} ${statusMessage}\n`);
33
38
  writeHeaders(res.headers.toArray());
34
39
  }
35
- if (argv.remain[1] !== undefined) {
40
+ if (positionals[1] !== undefined) {
36
41
  const html = await res.html();
37
42
  process.stdout.write(html
38
- .find(argv.remain[1])
43
+ .find(positionals[1])
39
44
  .map(el => el.toString())
40
45
  .join('') ?? '');
41
46
  }
@@ -75,8 +80,7 @@ function parseHeaders(list = []) {
75
80
  function writeHeaders(headers) {
76
81
  const stderr = process.stderr;
77
82
  for (let i = 0; i < headers.length; i += 2) {
78
- stderr.write(chalk.cyan(headers[i]) + `: ${headers[i + 1]}\n`);
83
+ stderr.write(styleText('cyan', headers[i], { stream: stderr }) + `: ${headers[i + 1]}\n`);
79
84
  }
80
85
  stderr.write('\n');
81
86
  }
82
- //# sourceMappingURL=get.js.map
package/lib/cli/repl.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * Repl command.
4
4
  */
package/lib/cli/repl.js CHANGED
@@ -13,4 +13,3 @@ replCommand.usage = `Usage: APPLICATION repl [OPTIONS]
13
13
  Options:
14
14
  -h, --help Show this summary of available options
15
15
  `;
16
- //# sourceMappingURL=repl.js.map
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * Routes command.
4
4
  */
package/lib/cli/routes.js CHANGED
@@ -1,13 +1,17 @@
1
+ import { parseArgs, styleText } from 'node:util';
1
2
  import { tablify } from '@mojojs/util';
2
- import chalk from 'chalk';
3
- import nopt from 'nopt';
4
3
  /**
5
4
  * Routes command.
6
5
  */
7
6
  export default async function routesCommand(app, args) {
8
- const parsed = nopt({ verbose: Boolean }, { v: '--verbose' }, args, 1);
7
+ const { values } = parseArgs({
8
+ args: args.slice(1),
9
+ options: { verbose: { type: 'boolean', short: 'v' } },
10
+ allowPositionals: true,
11
+ allowNegative: true
12
+ });
9
13
  const table = [];
10
- app.router.children.map(route => walk(route, 0, table, parsed.verbose));
14
+ app.router.children.map(route => walk(route, 0, table, values.verbose === true));
11
15
  process.stdout.write(tablify(table));
12
16
  }
13
17
  routesCommand.description = 'Show available routes';
@@ -27,9 +31,9 @@ function walk(route, depth, rows, verbose) {
27
31
  rows.push(row);
28
32
  // Methods
29
33
  const methods = route.methods;
30
- row.push(chalk.cyan(methods.length === 0 ? '*' : methods.map(method => method.toUpperCase()).join(',')));
34
+ row.push(styleText('cyan', methods.length === 0 ? '*' : methods.map(method => method.toUpperCase()).join(',')));
31
35
  // Name
32
- row.push(route.customName !== undefined ? chalk.green(route.customName) : chalk.red(route.defaultName ?? 'n/a'));
36
+ row.push(route.customName !== undefined ? styleText('green', route.customName) : styleText('red', route.defaultName ?? 'n/a'));
33
37
  // Regex (verbose)
34
38
  const pattern = route.pattern;
35
39
  pattern.match('/', { isEndpoint: route.isEndpoint() });
@@ -40,4 +44,3 @@ function walk(route, depth, rows, verbose) {
40
44
  route.children.map(child => walk(child, depth, rows, verbose));
41
45
  depth--;
42
46
  }
43
- //# sourceMappingURL=routes.js.map
@@ -1,4 +1,4 @@
1
- import type { MojoApp } from '../types.js';
1
+ import type { MojoApp } from '../types.ts';
2
2
  /**
3
3
  * Server command.
4
4
  */
package/lib/cli/server.js CHANGED
@@ -1,32 +1,39 @@
1
- import { Server } from '../server.js';
2
- import nopt from 'nopt';
1
+ import { parseArgs } from 'node:util';
2
+ import { Server } from "../server.js";
3
3
  const EVENTS = ['SIGINT', 'SIGTERM', 'SIGUSR2'];
4
4
  /**
5
5
  * Server command.
6
6
  */
7
7
  export default async function serverCommand(app, args) {
8
- const parsed = nopt({
9
- cluster: Boolean,
10
- 'headers-timeout': Number,
11
- 'keep-alive-timeout': Number,
12
- level: String,
13
- listen: [String, Array],
14
- proxy: Boolean,
15
- requests: Number,
16
- 'request-timeout': Number,
17
- workers: Number
18
- }, { c: '--cluster', L: '--level', l: '--listen', p: '--proxy', r: '--requests', w: '--workers' }, args, 1);
19
- if (parsed.level !== undefined)
20
- app.log.level = parsed.level;
8
+ const { values } = parseArgs({
9
+ args: args.slice(1),
10
+ options: {
11
+ cluster: { type: 'boolean', short: 'c' },
12
+ 'headers-timeout': { type: 'string' },
13
+ 'keep-alive-timeout': { type: 'string' },
14
+ level: { type: 'string', short: 'L' },
15
+ listen: { type: 'string', short: 'l', multiple: true },
16
+ 'max-websocket-size': { type: 'string' },
17
+ proxy: { type: 'boolean', short: 'p' },
18
+ requests: { type: 'string', short: 'r' },
19
+ 'request-timeout': { type: 'string' },
20
+ workers: { type: 'string', short: 'w' }
21
+ },
22
+ allowPositionals: true,
23
+ allowNegative: true
24
+ });
25
+ if (values.level !== undefined)
26
+ app.log.level = values.level;
21
27
  const server = new Server(app, {
22
- cluster: parsed.cluster,
23
- headersTimeout: parsed['headers-timeout'],
24
- keepAliveTimeout: parsed['keep-alive-timeout'],
25
- listen: parsed.listen,
26
- maxRequestsPerSocket: parsed.requests,
27
- requestTimeout: parsed['request-timeout'],
28
- reverseProxy: parsed.proxy,
29
- workers: parsed.workers
28
+ cluster: values.cluster,
29
+ headersTimeout: toNumber(values['headers-timeout']),
30
+ keepAliveTimeout: toNumber(values['keep-alive-timeout']),
31
+ listen: values.listen,
32
+ maxRequestsPerSocket: toNumber(values.requests),
33
+ maxWebSocketSize: toNumber(values['max-websocket-size']),
34
+ requestTimeout: toNumber(values['request-timeout']),
35
+ reverseProxy: values.proxy,
36
+ workers: toNumber(values.workers)
30
37
  });
31
38
  const listener = () => {
32
39
  EVENTS.forEach(signal => process.removeListener(signal, listener));
@@ -82,6 +89,9 @@ Options:
82
89
  -L, --level <level> Log level for application
83
90
  -l, --listen <location> One or more locations you want to listen on,
84
91
  defaults to "http://*:3000"
92
+ --max-websocket-size <bytes>
93
+ Maximum WebSocket message size, defaults to
94
+ 262144 (256 KiB)
85
95
  -p, --proxy Activate reverse proxy support
86
96
  -r, --requests <num> Maximum number of requests socket can handle
87
97
  before closing keep alive connection,
@@ -92,4 +102,11 @@ Options:
92
102
  -w, --workers <num> Number of workers to spawn in cluster mode,
93
103
  defaults to the number of available CPUs
94
104
  `;
95
- //# sourceMappingURL=server.js.map
105
+ function toNumber(value) {
106
+ if (value === undefined)
107
+ return undefined;
108
+ const number = Number(value);
109
+ if (value.trim() === '' || Number.isNaN(number))
110
+ throw new Error(`Invalid number "${value}"`);
111
+ return number;
112
+ }
@@ -1,4 +1,4 @@
1
- import { version } from '../core.js';
1
+ import { version } from "../core.js";
2
2
  import { tablify } from '@mojojs/util';
3
3
  /**
4
4
  * Version command.
@@ -18,4 +18,3 @@ versionCommand.usage = `Usage: APPLICATION version [OPTIONS]
18
18
  Options:
19
19
  -h, --help Show this summary of available options
20
20
  `;
21
- //# sourceMappingURL=version.js.map
package/lib/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { App } from './app.js';
1
+ import type { App } from './app.ts';
2
2
  interface Command {
3
3
  (app: App, args: string[]): Promise<void>;
4
4
  description: string;
package/lib/cli.js CHANGED
@@ -1,21 +1,22 @@
1
- import { loadModules } from './util.js';
1
+ import { parseArgs } from 'node:util';
2
+ import { loadModules } from "./util.js";
2
3
  import Path from '@mojojs/path';
3
4
  import { tablify } from '@mojojs/util';
4
- import nopt from 'nopt';
5
5
  /**
6
6
  * Command line interface class.
7
7
  */
8
8
  export class CLI {
9
+ /**
10
+ * Paths to search for commands.
11
+ */
12
+ commandPaths = [Path.currentFile().sibling('cli').toString()];
13
+ /**
14
+ * Registered commands.
15
+ */
16
+ commands = {};
17
+ _app;
18
+ _loaded = undefined;
9
19
  constructor(app) {
10
- /**
11
- * Paths to search for commands.
12
- */
13
- this.commandPaths = [Path.currentFile().sibling('cli').toString()];
14
- /**
15
- * Registered commands.
16
- */
17
- this.commands = {};
18
- this._loaded = undefined;
19
20
  this._app = new WeakRef(app);
20
21
  }
21
22
  /**
@@ -51,23 +52,29 @@ export class CLI {
51
52
  await this._loadCommands();
52
53
  if ((await app.hooks.runHook('command:init', app, commandArgs)) === true)
53
54
  return;
54
- const parsed = nopt({ help: Boolean, 'show-all': Boolean }, { h: '--help' }, commandArgs);
55
- const { argv } = parsed;
56
- if (argv.remain.length > 0) {
57
- const name = argv.original[0];
55
+ // Not strict, because the options of the command itself are unknown here
56
+ const original = commandArgs.slice(2);
57
+ const { values, positionals } = parseArgs({
58
+ args: original,
59
+ options: { help: { type: 'boolean', short: 'h' }, 'show-all': { type: 'boolean' } },
60
+ allowPositionals: true,
61
+ strict: false
62
+ });
63
+ if (positionals.length > 0) {
64
+ const name = original[0];
58
65
  const command = this.commands[name];
59
66
  if (command === undefined) {
60
67
  process.stdout.write(`Unknown command "${name}", maybe you need to install it?\n`);
61
68
  }
62
- else if (parsed.help === true) {
69
+ else if (values.help === true) {
63
70
  process.stdout.write(command.usage);
64
71
  }
65
72
  else {
66
- await command(app, argv.original);
73
+ await command(app, original);
67
74
  }
68
75
  }
69
76
  else {
70
- await this._listCommands(parsed['show-all']);
77
+ await this._listCommands(values['show-all'] === true);
71
78
  }
72
79
  await app.hooks.commandAfter(app, commandArgs);
73
80
  }
@@ -99,4 +106,3 @@ Commands:
99
106
  const footer = `
100
107
  See 'APPLICATION COMMAND --help' for more information on a specific command.
101
108
  `;
102
- //# sourceMappingURL=cli.js.map