svelte-realtime 0.4.0 → 0.4.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.
Files changed (3) hide show
  1. package/cli-utils.js +77 -0
  2. package/cli.js +14 -16
  3. package/package.json +2 -1
package/cli-utils.js ADDED
@@ -0,0 +1,77 @@
1
+ // @ts-check
2
+
3
+ const VALID_NAME_RE = /^[a-zA-Z0-9_-]+$/;
4
+ const VALID_TEMPLATES = ['minimal', 'example', 'demo'];
5
+
6
+ /**
7
+ * @param {string} [ua]
8
+ * @returns {'npm' | 'pnpm' | 'yarn' | 'bun'}
9
+ */
10
+ export function detectAgent(ua) {
11
+ const agent = ua ?? '';
12
+ if (agent.startsWith('pnpm')) return 'pnpm';
13
+ if (agent.startsWith('yarn')) return 'yarn';
14
+ if (agent.startsWith('bun')) return 'bun';
15
+ return 'npm';
16
+ }
17
+
18
+ /**
19
+ * Parse and validate CLI arguments. Returns an object or an error string.
20
+ * Parses in one pass so that flag values (e.g. --template minimal) are consumed
21
+ * and not mistaken for positional args.
22
+ * @param {string[]} argv - arguments (without node/script prefix)
23
+ * @param {{ dirExists?: (name: string) => boolean }} [opts]
24
+ * @returns {{ help: true } | { error: string } | { name?: string, template?: string }}
25
+ */
26
+ export function parseArgs(argv, opts) {
27
+ const positional = [];
28
+ let template;
29
+
30
+ for (let i = 0; i < argv.length; i++) {
31
+ const arg = argv[i];
32
+
33
+ if (arg === '--help' || arg === '-h') {
34
+ return { help: true };
35
+ }
36
+
37
+ if (arg === '--template') {
38
+ const next = argv[i + 1];
39
+ if (next === undefined || next.startsWith('-')) {
40
+ if (next === '--help' || next === '-h') return { help: true };
41
+ return { error: '--template requires a value: minimal, example, or demo.' };
42
+ }
43
+ template = argv[++i];
44
+ if (!VALID_TEMPLATES.includes(template)) {
45
+ return { error: `Unknown template: "${template}". Use minimal, example, or demo.` };
46
+ }
47
+ continue;
48
+ }
49
+
50
+ if (arg.startsWith('--template=')) {
51
+ template = arg.slice('--template='.length);
52
+ if (!template) {
53
+ return { error: '--template requires a value: minimal, example, or demo.' };
54
+ }
55
+ if (!VALID_TEMPLATES.includes(template)) {
56
+ return { error: `Unknown template: "${template}". Use minimal, example, or demo.` };
57
+ }
58
+ continue;
59
+ }
60
+
61
+ if (arg.startsWith('-')) continue;
62
+
63
+ positional.push(arg);
64
+ }
65
+
66
+ const name = positional[0];
67
+ if (name !== undefined) {
68
+ if (!VALID_NAME_RE.test(name)) {
69
+ return { error: `Invalid project name: "${name}". Use only letters, numbers, hyphens, and underscores.` };
70
+ }
71
+ if (opts?.dirExists?.(name)) {
72
+ return { error: `Directory "${name}" already exists.` };
73
+ }
74
+ }
75
+
76
+ return { name, template };
77
+ }
package/cli.js CHANGED
@@ -83,33 +83,26 @@ if (p.isCancel(template)) {
83
83
  const agent = detectAgent(process.env.npm_config_user_agent);
84
84
 
85
85
  if (template === 'demo') {
86
- const s = p.spinner();
87
- s.start('Cloning demo repository');
86
+ p.log.step('Cloning demo repository');
88
87
  run(`git clone ${DEMO_REPO} "${name}"`);
89
- s.stop('Cloned.');
90
88
 
91
- s.start('Installing dependencies');
89
+ p.log.step('Installing dependencies');
92
90
  run(`${agent} install`, dest);
93
- s.stop('Installed.');
94
91
 
95
92
  p.outro(`Done. cd ${name} && ${agent} run dev`);
96
93
  process.exit(0);
97
94
  }
98
95
 
99
- const s = p.spinner();
96
+ p.log.step('Creating SvelteKit project');
97
+ run(`npx -y sv create "${name}" --template minimal --types ts --no-add-ons --no-install`);
100
98
 
101
- s.start('Creating SvelteKit project');
102
- run(`npx -y sv create "${name}" --template minimal --types ts`);
103
- s.stop('Project created.');
104
-
105
- s.start('Installing dependencies');
99
+ p.log.step('Installing dependencies');
106
100
  const add = agent === 'npm' ? 'install' : 'add';
107
101
  run(`${agent} ${add} svelte-adapter-uws svelte-realtime`, dest);
108
102
  run(`${agent} ${add} uNetworking/uWebSockets.js#v20.60.0`, dest);
109
103
  run(`${agent} ${add} -D ws`, dest);
110
- s.stop('Dependencies installed.');
111
104
 
112
- s.start('Configuring svelte-realtime');
105
+ p.log.step('Configuring svelte-realtime');
113
106
 
114
107
  writeFileSync(
115
108
  join(dest, 'svelte.config.js'),
@@ -189,17 +182,22 @@ export const counter = live.stream('count', () => {
189
182
  );
190
183
  }
191
184
 
192
- s.stop('Configured.');
185
+ p.log.success('Configured.');
193
186
 
194
187
  p.outro(`Done. cd ${name} && ${agent} run dev`);
195
188
 
196
189
  // ---------------------------------------------------------------------------
197
190
 
191
+ /** @param {string} cmd @param {string} [cwd] */
198
192
  function run(cmd, cwd) {
199
193
  try {
200
- execSync(cmd, { cwd, stdio: 'pipe' });
194
+ execSync(cmd, {
195
+ cwd,
196
+ stdio: 'inherit',
197
+ env: { ...process.env, NODE_ENV: undefined }
198
+ });
201
199
  } catch (e) {
202
- p.cancel(`Command failed: ${cmd}\n${e.stderr || e.message}`);
200
+ p.cancel(`Command failed: ${cmd}\n${/** @type {any} */ (e).stderr || /** @type {any} */ (e).message}`);
203
201
  process.exit(1);
204
202
  }
205
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-realtime",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Realtime RPC and reactive subscriptions for SvelteKit, built on svelte-adapter-uws",
5
5
  "author": "Kevin Radziszewski",
6
6
  "license": "MIT",
@@ -52,6 +52,7 @@
52
52
  "devtools.js",
53
53
  "devtools.d.ts",
54
54
  "cli.js",
55
+ "cli-utils.js",
55
56
  "LICENSE",
56
57
  "README.md"
57
58
  ],