@vyriy/static 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,9 +17,16 @@ vyriy-static
17
17
  vyriy-static dist
18
18
  vyriy-static build
19
19
  vyriy-static public
20
+ vyriy-static --port 3000 dist
20
21
  ```
21
22
 
22
- When no directory is provided, the server tries `dist`, `build`, `public`, `out`, and then the current directory.
23
+ When no directory is provided to the CLI, it serves the current directory.
24
+
25
+ CLI flags:
26
+
27
+ - `--port <port>` or `-p <port>` sets the local server port.
28
+ - `--help` or `-h` prints command help.
29
+ - `--version` or `-v` prints the package version.
23
30
 
24
31
  ## API
25
32
 
@@ -44,6 +51,10 @@ export const spaRouter = withSpa(createRouter(), 'dist');
44
51
  const code = await staticServer({ directory: 'dist' });
45
52
  ```
46
53
 
47
- `useStatic({ directory, index, error })` serves files from a directory. `useSpa(options)` serves static files and falls back to the configured index file for missing `GET` and `HEAD` paths. `withStatic(router, options).static(path)` adds prefix-based static mounts. `withSpa(router, directoryOrOptions)` adds static-first SPA fallback behavior.
54
+ - `useStatic({ directory, index, error })` serves files from a directory.
55
+ - `useSpa(options)` serves static files and falls back to the configured index file for missing `GET` and `HEAD` paths.
56
+ - `withStatic(router, options).static(path)` adds prefix-based static mounts.
57
+ - `withSpa(router, directoryOrOptions)` adds static-first SPA fallback behavior.
48
58
 
49
59
  Defaults are `directory: 'dist'`, `index: 'index.html'`, and `error: '404.html'`.
60
+ When `staticServer()` is called without options, it tries `dist`, `build`, `public`, `out`, and then the current directory.
package/bin/index.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runStaticCli } from '../index.js';
3
+ await runStaticCli(process.argv.slice(2));
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@vyriy/static",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Static file and SPA serving helpers for Vyriy servers.",
5
5
  "type": "module",
6
- "bin": "./bin/vyriy-static.js",
6
+ "bin": {
7
+ "vs": "./bin/index.js",
8
+ "vyriy-static": "./bin/index.js"
9
+ },
7
10
  "dependencies": {
8
- "@vyriy/handler": "0.5.2",
9
- "@vyriy/router": "0.5.2",
10
- "@vyriy/server": "0.5.2"
11
+ "@vyriy/handler": "0.5.4",
12
+ "@vyriy/router": "0.5.4",
13
+ "@vyriy/server": "0.5.4"
11
14
  },
12
15
  "agents": "./AGENTS.md",
13
16
  "license": "MIT",
package/server.d.ts CHANGED
@@ -1,2 +1,14 @@
1
1
  import type { StaticServer } from './types.js';
2
+ export type StaticBinCommand = {
3
+ readonly type: 'help' | 'version';
4
+ } | {
5
+ readonly type: 'serve';
6
+ readonly directory: string;
7
+ readonly port?: string;
8
+ };
9
+ export type RunStaticCli = (args?: readonly string[], command?: string, alias?: false | string) => Promise<void>;
10
+ export declare const staticVersion: string;
11
+ export declare const createStaticHelpText: (command?: string, alias?: false | string) => string;
12
+ export declare const parseStaticBinArgs: (args: readonly string[]) => StaticBinCommand;
13
+ export declare const runStaticCli: RunStaticCli;
2
14
  export declare const staticServer: StaticServer;
package/server.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { server } from '@vyriy/server';
3
+ import packageJson from './package.json' with { type: 'json' };
3
4
  import { useStatic } from './use-static.js';
4
5
  const DIRECTORIES = [
5
6
  'dist',
@@ -7,8 +8,73 @@ const DIRECTORIES = [
7
8
  'public',
8
9
  'out',
9
10
  ];
11
+ const getOptionValue = (args, name, alias) => {
12
+ const inline = args.find((arg) => arg.startsWith(`${name}=`));
13
+ if (inline) {
14
+ return inline.slice(name.length + 1);
15
+ }
16
+ const index = args.findIndex((arg) => arg === name || arg === alias);
17
+ return index >= 0 ? args[index + 1] : undefined;
18
+ };
19
+ const isOptionValue = (args, index) => {
20
+ const previous = args[index - 1];
21
+ return previous === '--port' || previous === '-p';
22
+ };
10
23
  const resolveDirectory = (directory) => directory ?? DIRECTORIES.find((candidate) => existsSync(candidate)) ?? '.';
11
24
  const createStaticHandler = useStatic;
25
+ export const staticVersion = packageJson.version;
26
+ export const createStaticHelpText = (command = 'vyriy-static', alias = 'vs') => {
27
+ const aliasText = alias ? ` ${alias} [directory] Alias for ${command}\n` : '';
28
+ const aliasExampleText = alias ? `\n ${alias} .` : '';
29
+ return `Vyriy Static Server
30
+
31
+ Usage:
32
+ ${command} [directory] Serve a static directory (defaults to .)
33
+ ${command} --port 3000 dist Serve a directory on a specific port
34
+ ${aliasText}\
35
+ ${command} --help, -h Show help
36
+ ${command} --version, -v Show version
37
+
38
+ Options:
39
+ -p, --port <port> Port passed through the PORT environment variable
40
+
41
+ Examples:
42
+ ${command}
43
+ ${command} public
44
+ ${command} --port 3000 dist${aliasExampleText}`;
45
+ };
46
+ export const parseStaticBinArgs = (args) => {
47
+ if (args.includes('--help') || args.includes('-h')) {
48
+ return { type: 'help' };
49
+ }
50
+ if (args.includes('--version') || args.includes('-v')) {
51
+ return { type: 'version' };
52
+ }
53
+ return {
54
+ type: 'serve',
55
+ directory: args.find((arg, index) => !arg.startsWith('-') && !isOptionValue(args, index)) ?? '.',
56
+ port: getOptionValue(args, '--port', '-p'),
57
+ };
58
+ };
59
+ export const runStaticCli = async (args = [], command = 'vyriy-static', alias = 'vs') => {
60
+ const parsed = parseStaticBinArgs(args);
61
+ switch (parsed.type) {
62
+ case 'help':
63
+ console.log(createStaticHelpText(command, alias));
64
+ process.exitCode = 0;
65
+ break;
66
+ case 'version':
67
+ console.log(staticVersion);
68
+ process.exitCode = 0;
69
+ break;
70
+ case 'serve':
71
+ if (parsed.port) {
72
+ process.env.PORT = parsed.port;
73
+ }
74
+ process.exitCode = await staticServer({ directory: parsed.directory });
75
+ break;
76
+ }
77
+ };
12
78
  export const staticServer = async (options = {}) => {
13
79
  await Promise.resolve(server(createStaticHandler({ ...options, directory: resolveDirectory(options.directory) })));
14
80
  return 0;
package/types.d.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import type { ApiEvent, ApiResult, Handler } from '@vyriy/handler';
2
2
  import type { RouterApi } from '@vyriy/router';
3
- export type StaticServerOptions = StaticOptions;
4
3
  export type StaticOptions = {
5
4
  readonly directory?: string;
6
5
  readonly index?: string;
7
6
  readonly error?: string;
8
7
  };
9
8
  export type StaticHandler = Handler<ApiEvent, ApiResult>;
10
- export type StaticServer = (options?: StaticServerOptions) => Promise<number>;
9
+ export type StaticServer = (options?: StaticOptions) => Promise<number>;
11
10
  export type StaticRouterApi = Omit<RouterApi, 'delete' | 'fallback' | 'get' | 'patch' | 'post' | 'put'> & {
12
11
  static(path: string): StaticRouterApi;
13
12
  } & {
package/with-static.js CHANGED
@@ -1,7 +1,11 @@
1
1
  import { useStatic } from './use-static.js';
2
2
  const normalizeMount = (path) => {
3
3
  const mount = path.startsWith('/') ? path : `/${path}`;
4
- return mount === '/' ? mount : mount.replace(/\/+$/, '');
4
+ let end = mount.length;
5
+ while (end > 1 && mount[end - 1] === '/') {
6
+ end--;
7
+ }
8
+ return mount.slice(0, end);
5
9
  };
6
10
  const toStaticPath = (mount, requestPath) => {
7
11
  if (mount === '/') {
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- import { staticServer } from '../index.js';
3
- const directory = process.argv.find((arg, index) => index > 1 && !arg.startsWith('-')) ?? '.';
4
- void staticServer({ directory }).then((code) => {
5
- process.exitCode = code;
6
- });