selfnify-host 1.0.2 → 1.0.3

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 (2) hide show
  1. package/host.js +37 -9
  2. package/package.json +1 -1
package/host.js CHANGED
@@ -254,7 +254,7 @@ function request(method, apiPath, opts) {
254
254
  });
255
255
  }
256
256
 
257
- const bp = (name, sub) => '/bots/' + encodeURIComponent(name) + (sub || '');
257
+ const bp = (name, sub) => '/bots/' + encodeURIComponent(String(name).toLowerCase()) + (sub || '');
258
258
 
259
259
  // ----------------------------------------------------------------- helpers
260
260
 
@@ -283,7 +283,7 @@ function parseArgs(argv) {
283
283
 
284
284
  function requireName(name, usage) {
285
285
  if (!name) throw new CliError('which bot? usage: ' + usage);
286
- return name;
286
+ return String(name).toLowerCase();
287
287
  }
288
288
 
289
289
  function parseEnvFile(file) {
@@ -315,14 +315,19 @@ function parseStart(str) {
315
315
  let lang = null;
316
316
  if (['python', 'python3', 'py'].includes(cmd)) lang = 'python';
317
317
  else if (['node', 'nodejs'].includes(cmd)) lang = 'node';
318
+ else if (['ts', 'typescript', 'tsx', 'ts-node'].includes(cmd)) lang = 'typescript';
318
319
  else if (['cargo', 'rust'].includes(cmd)) lang = 'rust';
319
- if (!lang) throw new CliError('don\'t know how to run "' + str + '". Use: python, node or cargo');
320
+ if (!lang && ['npm', 'npx', 'pnpm', 'yarn', 'bun'].includes(cmd)) {
321
+ throw new CliError('"' + cmd + '" is not a start command here. Use: start node (JavaScript), start ts (TypeScript), start python or start cargo');
322
+ }
323
+ if (!lang) throw new CliError('don\'t know how to run "' + str + '". Use: python, node, ts or cargo');
320
324
  return { lang, entry: tokens[1] || null };
321
325
  }
322
326
 
323
327
  function detectStart(dir) {
324
328
  const has = (f) => fs.existsSync(path.join(dir, f));
325
329
  if (has('Cargo.toml')) return 'cargo';
330
+ if (has('tsconfig.json')) return 'ts';
326
331
  if (has('package.json')) return 'node';
327
332
  if (has('requirements.txt') || has('main.py') || has('bot.py')) return 'python';
328
333
  return null;
@@ -338,7 +343,26 @@ function nodeMain(dir) {
338
343
  return 'index.js';
339
344
  }
340
345
 
341
- const defaultEntry = (lang) => ({ python: 'main.py', node: 'index.js', rust: '' }[lang]);
346
+ function readPkg(dir) {
347
+ try {
348
+ return JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
349
+ } catch (e) {
350
+ return {};
351
+ }
352
+ }
353
+
354
+ function hasBuildScript(dir) {
355
+ const pkg = readPkg(dir);
356
+ return Boolean(pkg.scripts && pkg.scripts.build);
357
+ }
358
+
359
+ function tsMain(dir) {
360
+ const pkg = readPkg(dir);
361
+ if (pkg.main) return pkg.main;
362
+ return hasBuildScript(dir) ? 'dist/index.js' : 'src/index.ts';
363
+ }
364
+
365
+ const defaultEntry = (lang) => ({ python: 'main.py', node: 'index.js', typescript: 'dist/index.js', rust: '' }[lang]);
342
366
  const sanitizeName = (s) => s.toLowerCase().replace(/[^a-z0-9_-]/g, '-').replace(/^[-_]+/, '').slice(0, 32);
343
367
 
344
368
  async function packDir(dir) {
@@ -387,7 +411,7 @@ async function installBot(name, lang, progress) {
387
411
  }
388
412
  return secs + 's';
389
413
  }
390
- progress((lang === 'rust' ? 'building, Rust is slow, relax ' : 'installing ') + secs + 's');
414
+ progress((lang === 'rust' ? 'building, Rust is slow, relax ' : lang === 'typescript' ? 'installing and building ' : 'installing ') + secs + 's');
391
415
  if (secs > 3600) throw new CliError('install is taking over an hour. Check: host logs ' + name + ' --install');
392
416
  }
393
417
  }
@@ -617,10 +641,13 @@ async function deploy(opts, flags) {
617
641
  if (!startStr) throw new CliError('could not tell the language. Add: start python | node | cargo');
618
642
  const parsed = parseStart(startStr);
619
643
  const lang = parsed.lang;
620
- const main = opts.main || parsed.entry || (lang === 'node' ? nodeMain(dir) : defaultEntry(lang));
621
- const name = opts.name || sanitizeName(path.basename(dir));
644
+ const main = opts.main || parsed.entry || (lang === 'node' ? nodeMain(dir) : lang === 'typescript' ? tsMain(dir) : defaultEntry(lang));
645
+ const name = String(opts.name || sanitizeName(path.basename(dir))).toLowerCase();
622
646
  if (!NAME_RE.test(name)) throw new CliError('bad bot name "' + name + '": use a-z, 0-9, _ or -, max 32 characters');
623
- if (lang !== 'rust' && !fs.existsSync(path.join(dir, main))) throw new CliError('main file "' + main + '" not found in ' + dir);
647
+ const builtOnServer = lang === 'typescript' && !/\.(ts|mts|cts)$/.test(main) && hasBuildScript(dir);
648
+ if (lang !== 'rust' && !builtOnServer && !fs.existsSync(path.join(dir, main))) {
649
+ throw new CliError('main file "' + main + '" not found in ' + dir);
650
+ }
624
651
  let mem;
625
652
  if (flags.mem !== undefined) {
626
653
  mem = parseInt(flags.mem, 10);
@@ -776,7 +803,8 @@ function printHelp() {
776
803
  out(' host <path> start <cmd> main <file> name <bot>');
777
804
  out(c.dim(' host ./mybot start node main index.js name mybot'));
778
805
  out(c.dim(' host . start python main main.py name musicbot'));
779
- out(c.dim(' start = python | node | cargo main = file to run name = bot name'));
806
+ out(c.dim(' start = python | node | ts | cargo main = file to run name = bot name'));
807
+ out(c.dim(' TypeScript: host ./mybot start ts name mybot (the server runs your "build" script)'));
780
808
  out(c.dim(' leave out start/main/name and it guesses from your folder'));
781
809
  out();
782
810
  h(' Manage');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selfnify-host",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Deploy and manage bots (Python, Node.js, Rust) on the Selfnify host with one command.",
5
5
  "bin": {
6
6
  "host": "host.js",