@orxataguy/tyr 1.0.11-beta.1 → 1.0.11-beta.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.
package/bin/loader.mjs CHANGED
@@ -13,17 +13,68 @@
13
13
  */
14
14
 
15
15
  import { transformSync } from 'esbuild';
16
- import { readFileSync } from 'fs';
17
- import { fileURLToPath } from 'url';
16
+ import { existsSync, readFileSync } from 'fs';
17
+ import { fileURLToPath, pathToFileURL } from 'url';
18
+ import { resolve as resolvePath, dirname } from 'path';
18
19
 
19
- const TS_RE = /\.m?[ct]?ts$/;
20
+ const TS_RE = /\.m?[ct]?ts$/;
21
+ const NO_EXT_RE = /\/[^./]+$/; // path segment with no extension at the end
22
+ const EXT_MAP = { '.js': '.ts', '.mjs': '.mts', '.cjs': '.cts' };
23
+ const BARE_EXTS = ['.ts', '.mts', '.cts', '.js', '.mjs', '/index.ts', '/index.js'];
24
+
25
+ /**
26
+ * resolve() — handle two TypeScript-in-ESM conventions that Node cannot resolve natively:
27
+ *
28
+ * 1. Extensionless imports: './Container' → './Container.ts'
29
+ * 2. JS-extension imports: './Foo.js' → './Foo.ts' (TypeScript ESM idiom)
30
+ *
31
+ * Only relative imports are intercepted; bare specifiers (npm packages) go straight
32
+ * to the default resolver.
33
+ */
34
+ export function resolve(specifier, context, next) {
35
+ if (!specifier.startsWith('.') || !context.parentURL) {
36
+ return next(specifier, context);
37
+ }
38
+
39
+ const parentDir = dirname(fileURLToPath(context.parentURL));
40
+ const fullPath = resolvePath(parentDir, specifier);
41
+
42
+ // Case 1: specifier ends with a JS extension — try the equivalent TS extension
43
+ for (const [jsExt, tsExt] of Object.entries(EXT_MAP)) {
44
+ if (specifier.endsWith(jsExt)) {
45
+ const tsPath = fullPath.slice(0, -jsExt.length) + tsExt;
46
+ if (existsSync(tsPath)) {
47
+ return { url: pathToFileURL(tsPath).href, shortCircuit: true };
48
+ }
49
+ }
50
+ }
51
+
52
+ // Case 2: extensionless — probe TS then JS extensions
53
+ if (NO_EXT_RE.test(fullPath)) {
54
+ for (const ext of BARE_EXTS) {
55
+ const candidate = fullPath + ext;
56
+ if (existsSync(candidate)) {
57
+ return { url: pathToFileURL(candidate).href, shortCircuit: true };
58
+ }
59
+ }
60
+ }
61
+
62
+ return next(specifier, context);
63
+ }
20
64
 
21
65
  /**
22
66
  * load() — intercept every ESM import whose URL ends in a TypeScript extension.
23
- * Files inside node_modules are never transformed (they ship as JS already).
67
+ *
68
+ * We do NOT exclude node_modules: the tyr package itself ships as .ts source
69
+ * (bin/tyr.ts, src/core/Kernel.ts, etc.) and those files ARE under node_modules
70
+ * when installed globally. Node.js 24's built-in strip-types refuses to handle
71
+ * .ts files under node_modules, so our loader must cover them.
72
+ *
73
+ * The TS_RE regex already limits interception to .ts/.mts/.cts files — the
74
+ * compiled .js files that third-party packages ship will never match it.
24
75
  */
25
76
  export function load(url, context, next) {
26
- const isTs = TS_RE.test(url) && !url.includes('/node_modules/');
77
+ const isTs = TS_RE.test(url);
27
78
  if (!isTs) return next(url, context);
28
79
 
29
80
  const filePath = fileURLToPath(url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orxataguy/tyr",
3
- "version": "1.0.11-beta.1",
3
+ "version": "1.0.11-beta.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "tyr": "./bin/tyr.js"
@@ -4,15 +4,15 @@ import yaml from 'js-yaml';
4
4
  import dotenv from 'dotenv';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
6
6
  import { homedir } from 'os';
7
- import { Container } from './Container';
8
-
9
- import gen from './sys/gen';
10
- import rem from './sys/rem';
11
- import doc from './sys/doc';
12
- import ai from './sys/ai';
13
- import build from './sys/build';
14
- import config from './sys/config';
15
- import help from './sys/help';
7
+ import { Container } from './Container.ts';
8
+
9
+ import gen from './sys/gen.ts';
10
+ import rem from './sys/rem.ts';
11
+ import doc from './sys/doc.ts';
12
+ import ai from './sys/ai.ts';
13
+ import build from './sys/build.ts';
14
+ import config from './sys/config.ts';
15
+ import help from './sys/help.ts';
16
16
 
17
17
  import { TyrError } from './TyrError';
18
18