@warlock.js/core 4.0.2 → 4.0.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/bin/warlock.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { startCliServer } = require("./../cjs/starters/start-cli-server.js");
3
+ import { startCliServer } from "./../esm/starters/start-cli-server.js";
4
4
 
5
- startCliServer();
5
+ startCliServer();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warlock.js/core",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "A robust nodejs framework for building blazing fast applications",
5
5
  "main": "./cjs/index.js",
6
6
  "bin": {
@@ -30,8 +30,8 @@
30
30
  "@mongez/fs": "^3.0.5",
31
31
  "@mongez/http": "^2.2.10",
32
32
  "@mongez/localization": "^3.0.0",
33
- "@warlock.js/logger": "4.0.2",
34
- "@warlock.js/cascade": "4.0.2",
33
+ "@warlock.js/logger": "4.0.4",
34
+ "@warlock.js/cascade": "4.0.4",
35
35
  "@mongez/reinforcements": "^2.3.12",
36
36
  "commander": "^12.0.0",
37
37
  "@mongez/slug": "^1.0.7",
@@ -48,7 +48,8 @@
48
48
  "send": "^0.18.0",
49
49
  "prettier": "^3.1.0",
50
50
  "sharp": "^0.32.6",
51
- "@mongez/copper": "^1.0.1"
51
+ "@mongez/copper": "^1.0.1",
52
+ "fast-glob": "^3.3.3"
52
53
  },
53
54
  "devDependencies": {
54
55
  "fast-glob": "^3.3.3",
@@ -1,256 +0,0 @@
1
- import { fileExistsAsync, isDirectoryAsync } from "@mongez/fs";
2
- import { transform } from "esbuild";
3
- import fs from "fs/promises";
4
- import path from "path";
5
- import ts from "typescript";
6
- import { fileURLToPath, pathToFileURL } from "url";
7
- const configText = await fs.readFile(process.cwd() + "/tsconfig.json", "utf8");
8
-
9
- const { config: tsconfigRaw } = ts.parseConfigFileTextToJson(
10
- process.cwd() + "/tsconfig.json",
11
- configText,
12
- );
13
-
14
- let manifest = {
15
- aliases: {},
16
- importLookup: {},
17
- directoryIndexLookup: {},
18
- };
19
-
20
- const manifestPath = path.resolve(process.cwd(), ".warlock/manifest.json");
21
-
22
- const supportedExtensions = [".ts", ".tsx"];
23
-
24
- const cacheFilesDirectory = path.resolve(process.cwd(), ".warlock/.cache");
25
- const srcDirectory = path.resolve(process.cwd(), "src");
26
-
27
- /**
28
- * Normalize Windows paths into forward slashes (for URL consistency)
29
- */
30
- function normalizePath(p) {
31
- return p.replace(/\\/g, "/");
32
- }
33
-
34
- /**
35
- * Load manifest file for efficient path resolution.
36
- */
37
- async function loadManifest(force = false) {
38
- if (!force && Object.keys(manifest.importLookup).length) {
39
- return manifest;
40
- }
41
-
42
- try {
43
- const manifestRaw = JSON.parse(await fs.readFile(manifestPath, "utf8"));
44
- manifest = {
45
- aliases: manifestRaw.aliases ?? {},
46
- importLookup: manifestRaw.importLookup ?? {},
47
- directoryIndexLookup: manifestRaw.directoryIndexLookup ?? {},
48
- };
49
- } catch (err) {
50
- console.warn(
51
- "⚠️ Warlock loader: could not load manifest.json — using empty lookups.",
52
- );
53
- manifest = {
54
- aliases: {},
55
- importLookup: {},
56
- directoryIndexLookup: {},
57
- };
58
- }
59
-
60
- return manifest;
61
- }
62
-
63
- // Load manifest initially
64
- await loadManifest(true);
65
-
66
- /**
67
- * Resolve hook — maps aliases and missing extensions using manifest.
68
- */
69
- export async function resolve(specifier, context, nextResolve) {
70
- const { parentURL = import.meta.url } = context;
71
-
72
- // Skip custom resolution for node_modules - use default Node.js behavior
73
- if (
74
- specifier.includes("node_modules") ||
75
- parentURL.includes("node_modules")
76
- ) {
77
- return nextResolve(specifier, context, nextResolve);
78
- }
79
-
80
- const loadedManifest = await loadManifest();
81
-
82
- // 1. Handle tsconfig aliases using manifest
83
- for (const [alias, aliasInfo] of Object.entries(loadedManifest.aliases)) {
84
- if (specifier.startsWith(alias)) {
85
- const relativePart = specifier.slice(alias.length);
86
- const importPath = normalizePath(path.join(aliasInfo.path, relativePart));
87
-
88
- // Try direct import lookup first (e.g., "app/main" -> "app/main.ts")
89
- if (loadedManifest.importLookup[importPath]) {
90
- const fileInfo = loadedManifest.importLookup[importPath];
91
- const fullPath = path.resolve(srcDirectory, fileInfo.path);
92
- return {
93
- url: pathToFileURL(fullPath).href,
94
- shortCircuit: true,
95
- };
96
- }
97
-
98
- // Try directory index lookup (e.g., "app" -> "app/index.ts")
99
- if (loadedManifest.directoryIndexLookup[importPath]) {
100
- const fileInfo = loadedManifest.directoryIndexLookup[importPath];
101
- const fullPath = path.resolve(srcDirectory, fileInfo.path);
102
- return {
103
- url: pathToFileURL(fullPath).href,
104
- shortCircuit: true,
105
- };
106
- }
107
-
108
- // Fallback to file system checks if not in manifest (for new files)
109
- const resolvedPath = path.resolve(
110
- srcDirectory,
111
- aliasInfo.path,
112
- relativePart,
113
- );
114
- for (const extension of supportedExtensions) {
115
- if (await fileExistsAsync(resolvedPath + extension)) {
116
- return {
117
- url: pathToFileURL(resolvedPath + extension).href,
118
- shortCircuit: true,
119
- };
120
- }
121
- }
122
-
123
- if (await fileExistsAsync(path.resolve(resolvedPath, "index.ts"))) {
124
- return {
125
- url: pathToFileURL(path.resolve(resolvedPath, "index.ts")).href,
126
- shortCircuit: true,
127
- };
128
- }
129
-
130
- if (await fileExistsAsync(path.resolve(resolvedPath, "index.tsx"))) {
131
- return {
132
- url: pathToFileURL(path.resolve(resolvedPath, "index.tsx")).href,
133
- shortCircuit: true,
134
- };
135
- }
136
-
137
- throw new Error(`Failed to resolve file: ${specifier}`);
138
- }
139
- }
140
-
141
- // 2. Handle relative imports using manifest
142
- if (specifier.startsWith("./") || specifier.startsWith("../")) {
143
- const parentPath = fileURLToPath(parentURL);
144
- const filePath = path.resolve(path.dirname(parentPath), specifier);
145
- const extension = path.extname(filePath);
146
-
147
- // If already has extension, use it directly
148
- if (supportedExtensions.includes(extension)) {
149
- return { url: pathToFileURL(filePath).href, shortCircuit: true };
150
- }
151
-
152
- // Calculate the import path relative to src directory
153
- const relativeToSrc = normalizePath(path.relative(srcDirectory, filePath));
154
-
155
- // Try direct import lookup
156
- if (loadedManifest.importLookup[relativeToSrc]) {
157
- const fileInfo = loadedManifest.importLookup[relativeToSrc];
158
- const fullPath = path.resolve(srcDirectory, fileInfo.path);
159
- return {
160
- url: pathToFileURL(fullPath).href,
161
- shortCircuit: true,
162
- };
163
- }
164
-
165
- // Try directory index lookup
166
- if (loadedManifest.directoryIndexLookup[relativeToSrc]) {
167
- const fileInfo = loadedManifest.directoryIndexLookup[relativeToSrc];
168
- const fullPath = path.resolve(srcDirectory, fileInfo.path);
169
- return {
170
- url: pathToFileURL(fullPath).href,
171
- shortCircuit: true,
172
- };
173
- }
174
-
175
- // Fallback to file system checks for new files
176
- for (const ext of supportedExtensions) {
177
- const fullPath = filePath + ext;
178
- if (await fileExistsAsync(fullPath)) {
179
- return { url: pathToFileURL(fullPath).href, shortCircuit: true };
180
- }
181
- }
182
-
183
- if (await isDirectoryAsync(filePath)) {
184
- return {
185
- url: pathToFileURL(path.resolve(filePath, "index.ts")).href,
186
- shortCircuit: true,
187
- };
188
- }
189
-
190
- throw new Error(`Failed to resolve file: ${filePath}`);
191
- }
192
-
193
- // 3. Fallback to Node default resolver
194
- return nextResolve(specifier, context, nextResolve);
195
- }
196
-
197
- /**
198
- * Load hook — transpiles TS/TSX into ESM on the fly.
199
- */
200
- export async function load(url, context, nextLoad) {
201
- if (url.includes("node_modules")) {
202
- return nextLoad(url, context, nextLoad);
203
- }
204
-
205
- if (url.endsWith(".ts") || url.endsWith(".tsx")) {
206
- const filePath = fileURLToPath(url);
207
- const relativePath = path
208
- .relative(process.cwd(), filePath)
209
- .replace(/\\/g, "/");
210
-
211
- // we will create a cache file name by replacing / to - so we can store it in a single file
212
- // make sure to trim any . dots at beginning of the path
213
- const cacheFileName = relativePath.replace(/^\./, "").replace(/\//g, "-");
214
-
215
- // Fallback to individual file read (for new files not in bundle)
216
- try {
217
- const cachedFile = await fs.readFile(
218
- cacheFilesDirectory + "/" + cacheFileName,
219
- "utf8",
220
- );
221
-
222
- return {
223
- format: "module",
224
- source: cachedFile,
225
- shortCircuit: true,
226
- };
227
- } catch (error) {
228
- // File not in cache at all, transpile it
229
- const source = await fs.readFile(filePath, "utf8");
230
-
231
- const { code } = await transform(source, {
232
- loader: url.endsWith(".tsx") ? "tsx" : "ts",
233
- format: "esm",
234
- sourcemap: "inline",
235
- sourcefile: filePath,
236
- tsconfigRaw,
237
- });
238
-
239
- // if code length is zero, it means this was just an empty file or a types only file
240
- let finalCode = code;
241
- if (code.length === 0) {
242
- finalCode = "/*_EMPTY_FILE_*/";
243
- }
244
-
245
- fs.writeFile(path.resolve(cacheFilesDirectory, cacheFileName), finalCode);
246
-
247
- return {
248
- format: "module",
249
- source: code,
250
- shortCircuit: true,
251
- };
252
- }
253
- }
254
-
255
- return nextLoad(url, context, nextLoad);
256
- }