@orxataguy/tyr 1.0.44 → 1.0.46
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 +4 -2
- package/package.json +1 -1
- package/src/core/Logger.ts +2 -2
- package/src/core/TyrError.ts +1 -1
- package/src/core/sys/modules.ts +27 -9
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ Third parties can distribute commands as a `manifest.json` — a flat JSON map o
|
|
|
185
185
|
}
|
|
186
186
|
```
|
|
187
187
|
|
|
188
|
-
`$env` is optional and reserved (`$` can never appear in a command name, so it never collides with one). If present, it's downloaded as `~/.tyr
|
|
188
|
+
`$env` is optional and reserved (`$` can never appear in a command name, so it never collides with one). If present, it's downloaded as `~/.tyr/.env.<module-name>.example` — a template of whatever environment variables that module's commands expect. It follows the exact same install/skip/force-update rules as commands below, and `tyr --del <module-name>` removes it along with everything else that module owns.
|
|
189
189
|
|
|
190
190
|
Register one with `tyr --add`, which validates the manifest, records it in `~/.tyr/imported_modules.yaml`, and immediately downloads whatever commands (and `$env`, if present) are missing:
|
|
191
191
|
|
|
@@ -193,6 +193,8 @@ Register one with `tyr --add`, which validates the manifest, records it in `~/.t
|
|
|
193
193
|
tyr --add https://raw.githubusercontent.com/someuser/tyr-modules/main/manifest.json my-module
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
+
The module name is optional. If you omit it and the manifest URL is a `raw.githubusercontent.com` link, the repository name is used (`tyr-modules` for the URL above). For any other host, it falls back to a slug of the manifest file's own name.
|
|
197
|
+
|
|
196
198
|
```bash
|
|
197
199
|
tyr --modules # list registered modules
|
|
198
200
|
tyr --modules sync # re-check all registered manifests and install anything missing
|
|
@@ -225,7 +227,7 @@ Commit and push it, and anyone can install your commands with `tyr --add <raw-ur
|
|
|
225
227
|
- Requires a GitHub remote named `origin` — other hosts aren't supported, since the URLs only resolve through `raw.githubusercontent.com`.
|
|
226
228
|
- If `~/.tyr` isn't a git repository (or has no `origin` remote), `--manifest` refuses and tells you why instead of generating a broken file.
|
|
227
229
|
- Commands whose file lives outside `~/.tyr` (an absolute path elsewhere on disk) are skipped, since they can't be resolved to a URL in the repo.
|
|
228
|
-
- If `~/.tyr/.env.example` exists, it's automatically included as `$env`, so whoever runs `tyr --add` on your manifest gets it as
|
|
230
|
+
- If `~/.tyr/.env.example` exists, it's automatically included as `$env`, so whoever runs `tyr --add` on your manifest gets it as `.env.<module-name>.example`.
|
|
229
231
|
|
|
230
232
|
### `tyr chat [directory] [--port <n>] [--split <0-1>]`
|
|
231
233
|
|
package/package.json
CHANGED
package/src/core/Logger.ts
CHANGED
|
@@ -55,11 +55,11 @@ export function createLogger(isDebug: boolean): Logger {
|
|
|
55
55
|
writeToFile('SUCCESS', msg);
|
|
56
56
|
},
|
|
57
57
|
error: (msg) => {
|
|
58
|
-
|
|
58
|
+
console.error(chalk.red('✖'), msg);
|
|
59
59
|
writeToFile('ERROR', msg);
|
|
60
60
|
},
|
|
61
61
|
warn: (msg) => {
|
|
62
|
-
|
|
62
|
+
console.warn(chalk.yellow('⚠'), msg);
|
|
63
63
|
writeToFile('WARN', msg);
|
|
64
64
|
},
|
|
65
65
|
};
|
package/src/core/TyrError.ts
CHANGED
|
@@ -34,7 +34,7 @@ export class TyrError extends Error {
|
|
|
34
34
|
logger.error('Oops! An error occurred.');
|
|
35
35
|
logger.error(`↳ ${this.message}`);
|
|
36
36
|
|
|
37
|
-
if (this.originalError) {
|
|
37
|
+
if (this.originalError && isDebug) {
|
|
38
38
|
logger.error(` ↳ Caused by: ${this.extractErrorMessage(this.originalError)}`);
|
|
39
39
|
}
|
|
40
40
|
|
package/src/core/sys/modules.ts
CHANGED
|
@@ -63,13 +63,31 @@ function toSafeFilename(commandName: string): string {
|
|
|
63
63
|
return commandName.replace(/:/g, '-');
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
function
|
|
66
|
+
function sanitizeSlug(value: string): string {
|
|
67
|
+
const slug = value.toLowerCase().replace(/[^a-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
68
|
+
return slug || 'module';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Default module name when `tyr --add <url>` is called without one.
|
|
73
|
+
* For a raw.githubusercontent.com URL (the expected shape:
|
|
74
|
+
* raw.githubusercontent.com/<owner>/<repo>/<branch>/<path>) this uses the
|
|
75
|
+
* repository name, since that's what identifies where the module comes from.
|
|
76
|
+
* For any other host — a manifest can be served from anywhere, as long as
|
|
77
|
+
* it's https — falls back to a slug of the manifest file's own name.
|
|
78
|
+
*/
|
|
79
|
+
function defaultModuleNameFromUrl(url: string): string {
|
|
67
80
|
try {
|
|
68
81
|
const parsed = new URL(url);
|
|
69
|
-
const
|
|
82
|
+
const segments = parsed.pathname.split('/').filter(Boolean);
|
|
83
|
+
|
|
84
|
+
if (parsed.hostname === 'raw.githubusercontent.com' && segments.length >= 2) {
|
|
85
|
+
return sanitizeSlug(segments[1]);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const base = segments.pop() ?? 'module';
|
|
70
89
|
const withoutExt = base.replace(/\.json$/i, '').replace(/\.manifest$/i, '');
|
|
71
|
-
|
|
72
|
-
return slug || 'module';
|
|
90
|
+
return sanitizeSlug(withoutExt);
|
|
73
91
|
} catch {
|
|
74
92
|
return 'module';
|
|
75
93
|
}
|
|
@@ -257,7 +275,7 @@ export async function syncModules(context: TyrContext, options: { force?: boolea
|
|
|
257
275
|
}
|
|
258
276
|
|
|
259
277
|
if (envUrl) {
|
|
260
|
-
const envFileName =
|
|
278
|
+
const envFileName = `.env.${toSafeFilename(moduleName)}.example`;
|
|
261
279
|
const envDestPath = path.join(userRoot, envFileName);
|
|
262
280
|
const envManaged = lock.env![moduleName];
|
|
263
281
|
|
|
@@ -337,7 +355,7 @@ export async function addModule(context: TyrContext, manifestUrl: string, name?:
|
|
|
337
355
|
return;
|
|
338
356
|
}
|
|
339
357
|
|
|
340
|
-
const moduleName = name && isValidCommandName(name) ? name :
|
|
358
|
+
const moduleName = name && isValidCommandName(name) ? name : defaultModuleNameFromUrl(manifestUrl);
|
|
341
359
|
|
|
342
360
|
const modulesPath = path.join(userRoot, IMPORTED_MODULES_FILE);
|
|
343
361
|
const modulesFile = await loadYaml<ImportedModulesFile>(fs, modulesPath, { modules: {} });
|
|
@@ -358,7 +376,7 @@ export async function addModule(context: TyrContext, manifestUrl: string, name?:
|
|
|
358
376
|
* Unregisters a module: removes it from imported_modules.yaml, deletes every
|
|
359
377
|
* command file it's tracked as owning in the lockfile, drops those commands
|
|
360
378
|
* (and any aliases pointing at them) from map.yml, deletes its
|
|
361
|
-
*
|
|
379
|
+
* `.env.<module>.example` if one was imported, and clears their lockfile
|
|
362
380
|
* entries. The counterpart to `tyr --add` — closes the loop.
|
|
363
381
|
*/
|
|
364
382
|
export async function removeModule(context: TyrContext, moduleName: string): Promise<void> {
|
|
@@ -484,7 +502,7 @@ function parseGithubRemote(remoteUrl: string): GithubRepoInfo | null {
|
|
|
484
502
|
* handed to someone else, who registers it with `tyr --add <url>`.
|
|
485
503
|
*
|
|
486
504
|
* If ~/.tyr/.env.example exists, its raw URL is also included under the
|
|
487
|
-
* reserved `$env` key, so `tyr --add` downloads it as
|
|
505
|
+
* reserved `$env` key, so `tyr --add` downloads it as `.env.<module>.example`
|
|
488
506
|
* for whoever installs this manifest.
|
|
489
507
|
*
|
|
490
508
|
* Requires ~/.tyr to be a git repository linked to a GitHub remote — there's
|
|
@@ -558,7 +576,7 @@ export async function generateManifest(context: TyrContext): Promise<void> {
|
|
|
558
576
|
}
|
|
559
577
|
|
|
560
578
|
// If ~/.tyr has a .env.example, publish it too — tyr --add downloads it as
|
|
561
|
-
//
|
|
579
|
+
// .env.<module>.example so whoever installs this manifest knows which
|
|
562
580
|
// environment variables these commands expect.
|
|
563
581
|
const envExamplePath = path.join(userRoot, '.env.example');
|
|
564
582
|
let includedEnv = false;
|