@somewhere-tech/cli 0.28.5 → 0.29.1
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 +58 -13
- package/dist/commands/deploy.js +33 -8
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.js +298 -43
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/env.js +1 -1
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/project.js +2 -1
- package/dist/commands/project.js.map +1 -1
- package/dist/commands/promote.js +11 -12
- package/dist/commands/promote.js.map +1 -1
- package/dist/commands/rollback.js +1 -1
- package/dist/commands/rollback.js.map +1 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/lib/envfile-write.js +1 -1
- package/dist/lib/envfile-write.js.map +1 -1
- package/dist/lib/output.js +2 -2
- package/dist/lib/output.js.map +1 -1
- package/dist/local/compiler-core.js +24 -0
- package/dist/local/compiler-core.js.map +1 -0
- package/dist/local/compiler.js +444 -0
- package/dist/local/compiler.js.map +1 -0
- package/dist/local/dev-server.js +487 -0
- package/dist/local/dev-server.js.map +1 -0
- package/dist/local/loader.js +70 -9
- package/dist/local/loader.js.map +1 -1
- package/dist/local/loopback.js +54 -0
- package/dist/local/loopback.js.map +1 -0
- package/dist/local/runtime.js +1 -1
- package/dist/local/runtime.js.map +1 -1
- package/dist/local/server.js +12 -22
- package/dist/local/server.js.map +1 -1
- package/node_modules/esbuild-wasm/LICENSE.md +21 -0
- package/node_modules/esbuild-wasm/README.md +3 -0
- package/node_modules/esbuild-wasm/bin/esbuild +91 -0
- package/node_modules/esbuild-wasm/esbuild.wasm +0 -0
- package/node_modules/esbuild-wasm/esm/browser.d.ts +705 -0
- package/node_modules/esbuild-wasm/esm/browser.js +2393 -0
- package/node_modules/esbuild-wasm/esm/browser.min.js +20 -0
- package/node_modules/esbuild-wasm/lib/browser.d.ts +705 -0
- package/node_modules/esbuild-wasm/lib/browser.js +2438 -0
- package/node_modules/esbuild-wasm/lib/browser.min.js +22 -0
- package/node_modules/esbuild-wasm/lib/main.d.ts +705 -0
- package/node_modules/esbuild-wasm/lib/main.js +2051 -0
- package/node_modules/esbuild-wasm/package.json +19 -0
- package/node_modules/esbuild-wasm/wasm_exec.js +561 -0
- package/node_modules/esbuild-wasm/wasm_exec_node.js +39 -0
- package/npm-shrinkwrap.json +17 -2
- package/package.json +7 -5
- package/runtime/VENDOR.json +7 -0
- package/runtime/compiler/VENDOR.json +27 -0
- package/runtime/compiler/compile-core.cjs +1775 -0
- package/runtime/compiler/graph-contract.cjs +124 -0
- package/runtime/compiler/typed-functions.cjs +545 -0
- package/runtime/platform-context.mjs +5422 -1802
- package/runtime/sw-init.mjs +51 -5
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
import { extname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import chokidar from 'chokidar';
|
|
5
|
+
import { IGNORE, collectFiles } from '../lib/files.js';
|
|
6
|
+
import { bold, dim, green, red, teal, warn, yellow } from '../lib/output.js';
|
|
7
|
+
import { bumpGeneration } from './loader.js';
|
|
8
|
+
import { dispatchRequest, refreshRoutes } from './runtime.js';
|
|
9
|
+
import { CompileFailure } from './compiler.js';
|
|
10
|
+
import { serveLoopback } from './loopback.js';
|
|
11
|
+
const STATIC_MIME = {
|
|
12
|
+
'.html': 'text/html; charset=utf-8',
|
|
13
|
+
'.htm': 'text/html; charset=utf-8',
|
|
14
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
15
|
+
'.mjs': 'text/javascript; charset=utf-8',
|
|
16
|
+
'.cjs': 'text/javascript; charset=utf-8',
|
|
17
|
+
'.css': 'text/css; charset=utf-8',
|
|
18
|
+
'.json': 'application/json; charset=utf-8',
|
|
19
|
+
'.map': 'application/json; charset=utf-8',
|
|
20
|
+
'.svg': 'image/svg+xml',
|
|
21
|
+
'.png': 'image/png',
|
|
22
|
+
'.jpg': 'image/jpeg',
|
|
23
|
+
'.jpeg': 'image/jpeg',
|
|
24
|
+
'.gif': 'image/gif',
|
|
25
|
+
'.webp': 'image/webp',
|
|
26
|
+
'.avif': 'image/avif',
|
|
27
|
+
'.ico': 'image/x-icon',
|
|
28
|
+
'.bmp': 'image/bmp',
|
|
29
|
+
'.woff': 'font/woff',
|
|
30
|
+
'.woff2': 'font/woff2',
|
|
31
|
+
'.ttf': 'font/ttf',
|
|
32
|
+
'.otf': 'font/otf',
|
|
33
|
+
'.eot': 'application/vnd.ms-fontobject',
|
|
34
|
+
'.txt': 'text/plain; charset=utf-8',
|
|
35
|
+
'.md': 'text/markdown; charset=utf-8',
|
|
36
|
+
'.xml': 'application/xml; charset=utf-8',
|
|
37
|
+
'.wasm': 'application/wasm',
|
|
38
|
+
'.pdf': 'application/pdf',
|
|
39
|
+
'.mp3': 'audio/mpeg',
|
|
40
|
+
'.mp4': 'video/mp4',
|
|
41
|
+
'.webm': 'video/webm',
|
|
42
|
+
'.wav': 'audio/wav',
|
|
43
|
+
'.ogg': 'audio/ogg',
|
|
44
|
+
};
|
|
45
|
+
const RELOAD_PATH = '/__somewhere_dev_reload';
|
|
46
|
+
/** Files whose change triggers a rebuild of the frontend bundle. */
|
|
47
|
+
const SOURCE_EXTS = /\.(tsx?|jsx?|mts|cts|mjs|cjs|css|scss|sass|less|html|json|svg|png|jpe?g|gif|webp|avif|ico|woff2?|ttf|otf)$/i;
|
|
48
|
+
/** Files whose change also invalidates the loaded function modules. */
|
|
49
|
+
const FUNCTION_EXTS = /\.(ts|tsx|mts|js|mjs|jsx|json)$/i;
|
|
50
|
+
function stamp() {
|
|
51
|
+
const d = new Date();
|
|
52
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
53
|
+
return `[${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}]`;
|
|
54
|
+
}
|
|
55
|
+
function statusColor(status) {
|
|
56
|
+
if (status >= 500)
|
|
57
|
+
return red;
|
|
58
|
+
if (status >= 400)
|
|
59
|
+
return yellow;
|
|
60
|
+
return green;
|
|
61
|
+
}
|
|
62
|
+
async function toFetchRequest(req, port) {
|
|
63
|
+
const url = `http://localhost:${port}${req.url ?? '/'}`;
|
|
64
|
+
const method = (req.method ?? 'GET').toUpperCase();
|
|
65
|
+
const headers = new Headers();
|
|
66
|
+
for (const [k, v] of Object.entries(req.headers)) {
|
|
67
|
+
if (v === undefined)
|
|
68
|
+
continue;
|
|
69
|
+
if (Array.isArray(v))
|
|
70
|
+
for (const item of v)
|
|
71
|
+
headers.append(k, item);
|
|
72
|
+
else
|
|
73
|
+
headers.set(k, v);
|
|
74
|
+
}
|
|
75
|
+
let body;
|
|
76
|
+
if (method !== 'GET' && method !== 'HEAD') {
|
|
77
|
+
const chunks = [];
|
|
78
|
+
for await (const chunk of req)
|
|
79
|
+
chunks.push(chunk);
|
|
80
|
+
body = Buffer.concat(chunks);
|
|
81
|
+
}
|
|
82
|
+
return new Request(url, { method, headers, body });
|
|
83
|
+
}
|
|
84
|
+
async function writeNodeResponse(response, res) {
|
|
85
|
+
const headers = {};
|
|
86
|
+
for (const [k, v] of response.headers.entries()) {
|
|
87
|
+
if (k.toLowerCase() === 'set-cookie')
|
|
88
|
+
continue;
|
|
89
|
+
headers[k] = v;
|
|
90
|
+
}
|
|
91
|
+
const cookies = response.headers.getSetCookie();
|
|
92
|
+
if (cookies.length)
|
|
93
|
+
headers['set-cookie'] = cookies;
|
|
94
|
+
res.writeHead(response.status, headers);
|
|
95
|
+
if (response.body) {
|
|
96
|
+
Readable.fromWeb(response.body).pipe(res);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
res.end();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function safeStat(p) {
|
|
103
|
+
try {
|
|
104
|
+
return statSync(p);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function resolveWithinCwd(cwd, rel) {
|
|
111
|
+
const root = resolve(cwd);
|
|
112
|
+
const abs = resolve(root, rel);
|
|
113
|
+
if (abs !== root && !abs.startsWith(root + sep))
|
|
114
|
+
return null;
|
|
115
|
+
return abs;
|
|
116
|
+
}
|
|
117
|
+
/** Never serve `.env`, `.git`, `.somewhere.json`, node_modules, … off disk. */
|
|
118
|
+
function isBlockedPath(rel) {
|
|
119
|
+
return rel
|
|
120
|
+
.split('/')
|
|
121
|
+
.some((seg) => seg === '..' || IGNORE.has(seg) || (seg !== '' && seg.startsWith('.')));
|
|
122
|
+
}
|
|
123
|
+
// ─── Live reload + error overlay, injected into the served HTML ─────────────
|
|
124
|
+
const CLIENT_SCRIPT = `
|
|
125
|
+
<script>(function(){
|
|
126
|
+
var es = new EventSource(${JSON.stringify(RELOAD_PATH)});
|
|
127
|
+
var box = null;
|
|
128
|
+
function overlay(err){
|
|
129
|
+
if (!box) {
|
|
130
|
+
box = document.createElement('div');
|
|
131
|
+
box.style.cssText = 'position:fixed;inset:0;z-index:2147483647;background:rgba(11,13,16,.94);'
|
|
132
|
+
+ 'color:#e6e6e6;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;padding:32px;overflow:auto;'
|
|
133
|
+
+ '-webkit-font-smoothing:antialiased';
|
|
134
|
+
document.body.appendChild(box);
|
|
135
|
+
}
|
|
136
|
+
var rows = (err.locations||[]).map(function(l){
|
|
137
|
+
var where = l.file + (l.line ? ':' + l.line + (l.column ? ':' + l.column : '') : '');
|
|
138
|
+
return '<div style="margin:14px 0"><div style="color:#7fd1ff">' + esc(where) + '</div>'
|
|
139
|
+
+ '<div style="color:#ffb4a2;white-space:pre-wrap">' + esc(l.text) + '</div></div>';
|
|
140
|
+
}).join('');
|
|
141
|
+
box.innerHTML = '<div style="color:#ff6b6b;font-weight:600;letter-spacing:.02em">COMPILE FAILED</div>'
|
|
142
|
+
+ (rows || '<div style="margin:14px 0;white-space:pre-wrap">' + esc(err.message) + '</div>')
|
|
143
|
+
+ '<div style="margin-top:24px;color:#8b949e">The last working page is still underneath. '
|
|
144
|
+
+ 'Fix and save — this clears itself.</div>';
|
|
145
|
+
box.style.display = 'block';
|
|
146
|
+
}
|
|
147
|
+
function esc(s){ return String(s == null ? '' : s).replace(/[&<>]/g, function(c){
|
|
148
|
+
return c === '&' ? '&' : c === '<' ? '<' : '>'; }); }
|
|
149
|
+
es.onmessage = function(e){
|
|
150
|
+
var msg = JSON.parse(e.data);
|
|
151
|
+
if (msg.type === 'reload') location.reload();
|
|
152
|
+
else if (msg.type === 'error') overlay(msg.error);
|
|
153
|
+
else if (msg.type === 'ok' && box) { box.style.display = 'none'; box.innerHTML = ''; }
|
|
154
|
+
};
|
|
155
|
+
})();</script>`;
|
|
156
|
+
function injectClient(html) {
|
|
157
|
+
if (/<\/body\s*>/i.test(html))
|
|
158
|
+
return html.replace(/<\/body\s*>/i, `${CLIENT_SCRIPT}\n</body>`);
|
|
159
|
+
return html + CLIENT_SCRIPT;
|
|
160
|
+
}
|
|
161
|
+
// ─── Terminal rendering of a compile failure ────────────────────────────────
|
|
162
|
+
function printCompileFailure(failure, cwd) {
|
|
163
|
+
console.log(red(' compile failed'));
|
|
164
|
+
if (!failure.locations.length) {
|
|
165
|
+
console.log(` ${failure.message}`);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const loc of failure.locations) {
|
|
169
|
+
const where = loc.line ? `${loc.file}:${loc.line}${loc.column ? `:${loc.column}` : ''}` : loc.file;
|
|
170
|
+
console.log(` ${teal(where)} ${loc.text}`);
|
|
171
|
+
if (loc.line) {
|
|
172
|
+
const abs = resolveWithinCwd(cwd, loc.file);
|
|
173
|
+
const line = abs && safeStat(abs)?.isFile()
|
|
174
|
+
? readFileSync(abs, 'utf8').split('\n')[loc.line - 1]
|
|
175
|
+
: undefined;
|
|
176
|
+
if (line !== undefined) {
|
|
177
|
+
console.log(dim(` ${String(loc.line).padStart(4)} │ ${line}`));
|
|
178
|
+
if (loc.column)
|
|
179
|
+
console.log(dim(` │ ${' '.repeat(Math.max(0, loc.column - 1))}^`));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
console.log(dim(' the last working page is still up — fix and save again'));
|
|
184
|
+
}
|
|
185
|
+
export async function startDevServer(opts) {
|
|
186
|
+
const { port, cwd, compiler, state } = opts;
|
|
187
|
+
const build = { output: null, failure: null };
|
|
188
|
+
const clients = new Set();
|
|
189
|
+
function broadcast(payload) {
|
|
190
|
+
const frame = `data: ${JSON.stringify(payload)}\n\n`;
|
|
191
|
+
for (const client of clients) {
|
|
192
|
+
try {
|
|
193
|
+
client.write(frame);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
clients.delete(client);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Compile the project as it is on disk right now.
|
|
202
|
+
*
|
|
203
|
+
* `changedAt` is when the file write landed, so the printed number is the
|
|
204
|
+
* developer's actual save-to-served latency and not just compiler time.
|
|
205
|
+
*/
|
|
206
|
+
async function rebuild(changedAt, label) {
|
|
207
|
+
const sources = collectFiles(cwd);
|
|
208
|
+
try {
|
|
209
|
+
const output = await compiler.compile({ files: sources.files, binaryFiles: sources.binaryFiles });
|
|
210
|
+
build.output = output;
|
|
211
|
+
build.failure = null;
|
|
212
|
+
const ms = Date.now() - changedAt;
|
|
213
|
+
console.log(`${dim(stamp())} ${teal(label)} ${green('✓')} ${dim(`${ms}ms`)}`);
|
|
214
|
+
for (const w of output.warnings)
|
|
215
|
+
warn(` ${w}`);
|
|
216
|
+
opts.onRebuild?.(ms);
|
|
217
|
+
broadcast({ type: 'reload' });
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
const failure = err instanceof CompileFailure
|
|
221
|
+
? err
|
|
222
|
+
: new CompileFailure(err instanceof Error ? err.message : String(err), []);
|
|
223
|
+
build.failure = failure;
|
|
224
|
+
console.log(`${dim(stamp())} ${teal(label)} ${red('✗')} ${dim(`${Date.now() - changedAt}ms`)}`);
|
|
225
|
+
printCompileFailure(failure, cwd);
|
|
226
|
+
broadcast({
|
|
227
|
+
type: 'error',
|
|
228
|
+
error: { message: failure.message, locations: failure.locations },
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// First build before the port opens, so the first request never races it.
|
|
233
|
+
await rebuild(Date.now(), 'initial build');
|
|
234
|
+
function serveCompiled(pathname, method) {
|
|
235
|
+
const name = pathname.slice('/_compiled/'.length);
|
|
236
|
+
const text = build.output?.chunks[name];
|
|
237
|
+
if (text === undefined)
|
|
238
|
+
return null;
|
|
239
|
+
return new Response(method === 'HEAD' ? null : text, {
|
|
240
|
+
status: 200,
|
|
241
|
+
headers: {
|
|
242
|
+
'Content-Type': name.endsWith('.css') ? 'text/css; charset=utf-8' : 'text/javascript; charset=utf-8',
|
|
243
|
+
'Cache-Control': 'no-store',
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function htmlResponse(html, method) {
|
|
248
|
+
const body = injectClient(html);
|
|
249
|
+
return new Response(method === 'HEAD' ? null : body, {
|
|
250
|
+
status: 200,
|
|
251
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' },
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function fileResponse(abs, method) {
|
|
255
|
+
const buf = readFileSync(abs);
|
|
256
|
+
const type = STATIC_MIME[extname(abs).toLowerCase()] ?? 'application/octet-stream';
|
|
257
|
+
return new Response(method === 'HEAD' ? null : buf, {
|
|
258
|
+
status: 200,
|
|
259
|
+
headers: {
|
|
260
|
+
'Content-Type': type,
|
|
261
|
+
'Content-Length': String(buf.byteLength),
|
|
262
|
+
'Cache-Control': 'no-store',
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/** The app's HTML: the compiled rewrite when we have one, the raw file when we don't. */
|
|
267
|
+
function appHtml(method) {
|
|
268
|
+
if (build.output?.html)
|
|
269
|
+
return htmlResponse(build.output.html, method);
|
|
270
|
+
const abs = resolveWithinCwd(cwd, 'index.html');
|
|
271
|
+
if (abs && safeStat(abs)?.isFile())
|
|
272
|
+
return htmlResponse(readFileSync(abs, 'utf8'), method);
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
function serveFrontend(request) {
|
|
276
|
+
const method = request.method.toUpperCase();
|
|
277
|
+
if (method !== 'GET' && method !== 'HEAD')
|
|
278
|
+
return null;
|
|
279
|
+
let pathname;
|
|
280
|
+
try {
|
|
281
|
+
pathname = decodeURIComponent(new URL(request.url).pathname);
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
if (pathname.startsWith('/_compiled/')) {
|
|
287
|
+
const compiled = serveCompiled(pathname, method);
|
|
288
|
+
return compiled ? { response: compiled, label: `compiled:${pathname.slice(11)}` } : null;
|
|
289
|
+
}
|
|
290
|
+
const rel = pathname.replace(/^\/+/, '');
|
|
291
|
+
if (rel === '' || rel === 'index.html') {
|
|
292
|
+
const html = appHtml(method);
|
|
293
|
+
return html ? { response: html, label: 'index.html' } : null;
|
|
294
|
+
}
|
|
295
|
+
if (!isBlockedPath(rel)) {
|
|
296
|
+
const abs = resolveWithinCwd(cwd, rel);
|
|
297
|
+
if (abs) {
|
|
298
|
+
const st = safeStat(abs);
|
|
299
|
+
if (st?.isFile())
|
|
300
|
+
return { response: fileResponse(abs, method), label: `static:${rel}` };
|
|
301
|
+
if (st?.isDirectory()) {
|
|
302
|
+
const idx = resolveWithinCwd(cwd, join(rel, 'index.html'));
|
|
303
|
+
if (idx && safeStat(idx)?.isFile()) {
|
|
304
|
+
return { response: htmlResponse(readFileSync(idx, 'utf8'), method), label: `static:${rel}/index.html` };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Client-side route → the app shell.
|
|
310
|
+
if (extname(pathname) === '') {
|
|
311
|
+
const html = appHtml(method);
|
|
312
|
+
if (html)
|
|
313
|
+
return { response: html, label: 'index.html (spa)' };
|
|
314
|
+
}
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
const handleRequest = (req, res) => {
|
|
318
|
+
void (async () => {
|
|
319
|
+
// The reload channel is a long-lived stream, not a request/response.
|
|
320
|
+
if ((req.url ?? '').split('?')[0] === RELOAD_PATH) {
|
|
321
|
+
res.writeHead(200, {
|
|
322
|
+
'Content-Type': 'text/event-stream',
|
|
323
|
+
'Cache-Control': 'no-store',
|
|
324
|
+
Connection: 'keep-alive',
|
|
325
|
+
});
|
|
326
|
+
res.write(': connected\n\n');
|
|
327
|
+
clients.add(res);
|
|
328
|
+
// A page that connects while the build is broken gets the overlay
|
|
329
|
+
// immediately rather than after the next save.
|
|
330
|
+
if (build.failure) {
|
|
331
|
+
res.write(`data: ${JSON.stringify({ type: 'error', error: { message: build.failure.message, locations: build.failure.locations } })}\n\n`);
|
|
332
|
+
}
|
|
333
|
+
req.on('close', () => clients.delete(res));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const t0 = Date.now();
|
|
337
|
+
let request;
|
|
338
|
+
try {
|
|
339
|
+
request = await toFetchRequest(req, port);
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
343
|
+
res.end(JSON.stringify({ ok: false, error: 'BAD_REQUEST', message: String(err) }));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
let route = null;
|
|
347
|
+
let response = null;
|
|
348
|
+
let handlerError;
|
|
349
|
+
if (state) {
|
|
350
|
+
const dispatched = await dispatchRequest(request, state);
|
|
351
|
+
if (dispatched.route) {
|
|
352
|
+
response = dispatched.response;
|
|
353
|
+
route = dispatched.route;
|
|
354
|
+
handlerError = dispatched.error;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (!response) {
|
|
358
|
+
const served = serveFrontend(request);
|
|
359
|
+
if (served) {
|
|
360
|
+
response = served.response;
|
|
361
|
+
route = served.label;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!response) {
|
|
365
|
+
response = new Response(JSON.stringify({ ok: false, error: 'NOT_FOUND' }), {
|
|
366
|
+
status: 404,
|
|
367
|
+
headers: { 'Content-Type': 'application/json' },
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
const ms = Date.now() - t0;
|
|
371
|
+
const color = statusColor(response.status);
|
|
372
|
+
console.log(`${dim(stamp())} ${request.method} ${new URL(request.url).pathname} ${color(String(response.status))} ${dim(`${ms}ms`)}${route ? dim(` → ${route}`) : ''}`);
|
|
373
|
+
// A function that threw prints its REAL stack here — this is your own
|
|
374
|
+
// terminal, and a stack you cannot see is a bug you cannot fix.
|
|
375
|
+
if (handlerError) {
|
|
376
|
+
const e = handlerError;
|
|
377
|
+
console.error(red(e instanceof Error ? e.stack ?? e.message : String(e)));
|
|
378
|
+
}
|
|
379
|
+
await writeNodeResponse(response, res);
|
|
380
|
+
})().catch((err) => {
|
|
381
|
+
console.error(red(`Internal dev-server error: ${err instanceof Error ? err.stack ?? err.message : String(err)}`));
|
|
382
|
+
if (!res.headersSent)
|
|
383
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
384
|
+
res.end(JSON.stringify({ ok: false, error: 'DEV_SERVER_ERROR', message: 'See terminal.' }));
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
const { servers } = await serveLoopback(handleRequest, port, (p) => {
|
|
388
|
+
console.error(red(`Port ${p} is already in use — pass --port <n> to pick another.`));
|
|
389
|
+
process.exit(1);
|
|
390
|
+
});
|
|
391
|
+
const url = `http://localhost:${port}`;
|
|
392
|
+
console.log('');
|
|
393
|
+
console.log(`${green('▲')} ${bold('somewhere dev')} ${dim('— your app, compiled by the platform, on your machine')}`);
|
|
394
|
+
console.log(`${teal('🌐')} ${bold('Local:')} ${teal(url)}`);
|
|
395
|
+
if (build.output) {
|
|
396
|
+
console.log(dim(` ${build.output.entry} → /_compiled/${build.output.entryChunk}`));
|
|
397
|
+
}
|
|
398
|
+
if (state) {
|
|
399
|
+
for (const r of state.routes)
|
|
400
|
+
console.log(` ${dim('•')} ${r.displayPath} ${dim(`(${r.file})`)}`);
|
|
401
|
+
if (state.missingEnvKeys.length) {
|
|
402
|
+
warn(`Platform env keys with no local value (access will throw): ${state.missingEnvKeys.join(', ')}. ` +
|
|
403
|
+
'Add them to .env in this directory to use them locally.');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
console.log(dim(' same app, same data, same build. Save a file. Ctrl-C to stop.\n'));
|
|
407
|
+
opts.onListening?.(url);
|
|
408
|
+
// ─── Watch ────────────────────────────────────────────────────────────────
|
|
409
|
+
//
|
|
410
|
+
// One debounce window for both jobs: a save that touches a function AND a
|
|
411
|
+
// component rebuilds the bundle and reloads the function modules once.
|
|
412
|
+
let timer = null;
|
|
413
|
+
let running = false;
|
|
414
|
+
let pendingLabel = '';
|
|
415
|
+
let pendingSince = 0;
|
|
416
|
+
let pendingStructural = false;
|
|
417
|
+
let pendingFunctions = false;
|
|
418
|
+
const flush = async () => {
|
|
419
|
+
if (running) {
|
|
420
|
+
timer = setTimeout(() => void flush(), 40);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const label = pendingLabel;
|
|
424
|
+
const since = pendingSince;
|
|
425
|
+
const structural = pendingStructural;
|
|
426
|
+
const functions = pendingFunctions;
|
|
427
|
+
pendingLabel = '';
|
|
428
|
+
pendingSince = 0;
|
|
429
|
+
pendingStructural = false;
|
|
430
|
+
pendingFunctions = false;
|
|
431
|
+
if (!label)
|
|
432
|
+
return;
|
|
433
|
+
running = true;
|
|
434
|
+
try {
|
|
435
|
+
if (functions) {
|
|
436
|
+
bumpGeneration();
|
|
437
|
+
if (structural && state) {
|
|
438
|
+
try {
|
|
439
|
+
refreshRoutes(state);
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
console.error(red(`Route compile failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
await rebuild(since, label);
|
|
447
|
+
}
|
|
448
|
+
finally {
|
|
449
|
+
running = false;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
const note = (rel, structural) => {
|
|
453
|
+
if (!SOURCE_EXTS.test(rel))
|
|
454
|
+
return;
|
|
455
|
+
if (!pendingSince)
|
|
456
|
+
pendingSince = Date.now();
|
|
457
|
+
pendingLabel = pendingLabel && pendingLabel !== rel ? `${rel} (+more)` : rel;
|
|
458
|
+
pendingStructural ||= structural;
|
|
459
|
+
pendingFunctions ||= FUNCTION_EXTS.test(rel);
|
|
460
|
+
if (timer)
|
|
461
|
+
clearTimeout(timer);
|
|
462
|
+
// Short window: long enough to coalesce an editor's write burst, short
|
|
463
|
+
// enough that it is not the thing the developer is waiting on.
|
|
464
|
+
timer = setTimeout(() => void flush(), 30);
|
|
465
|
+
};
|
|
466
|
+
const watcher = chokidar.watch(cwd, {
|
|
467
|
+
ignoreInitial: true,
|
|
468
|
+
ignored: (p) => {
|
|
469
|
+
const rel = relative(cwd, p);
|
|
470
|
+
if (!rel || rel.startsWith('..'))
|
|
471
|
+
return false;
|
|
472
|
+
return rel
|
|
473
|
+
.split(/[\\/]/)
|
|
474
|
+
.some((seg) => IGNORE.has(seg) || (seg.startsWith('.') && seg !== '.' && seg !== ''));
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
watcher.on('change', (abs) => note(relative(cwd, abs), false));
|
|
478
|
+
watcher.on('add', (abs) => note(relative(cwd, abs), true));
|
|
479
|
+
watcher.on('unlink', (abs) => note(relative(cwd, abs), true));
|
|
480
|
+
process.on('SIGINT', () => {
|
|
481
|
+
console.log(`\n${dim('Stopped.')}`);
|
|
482
|
+
for (const s of servers)
|
|
483
|
+
s.close();
|
|
484
|
+
watcher.close().finally(() => process.exit(0));
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
//# sourceMappingURL=dev-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../../src/local/dev-server.ts"],"names":[],"mappings":"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"}
|
package/dist/local/loader.js
CHANGED
|
@@ -9,7 +9,19 @@
|
|
|
9
9
|
* directory index files) for relative imports originating inside the
|
|
10
10
|
* project.
|
|
11
11
|
*
|
|
12
|
-
* 2.
|
|
12
|
+
* 2. Bare specifiers the project has not installed — `import { createClient }
|
|
13
|
+
* from '@somewhere-tech/sdk'` in api/data.ts. Deployed, the platform
|
|
14
|
+
* resolves it; locally, Node looks only in the project's node_modules, so a
|
|
15
|
+
* project that has never run `npm install` renders its frontend fine (the
|
|
16
|
+
* compiler resolves the app's dependencies into the CLI's cache) and then
|
|
17
|
+
* 500s on every function with ERR_MODULE_NOT_FOUND — the loop half-working
|
|
18
|
+
* in the most confusing possible way (tsk_3269026d). A bare specifier Node
|
|
19
|
+
* cannot find is retried against the SAME search path the compiler used, by
|
|
20
|
+
* re-resolving with a parentURL rooted in each cache dir so package
|
|
21
|
+
* `exports` maps and subpaths behave exactly as Node would. The project's
|
|
22
|
+
* own node_modules always wins; the cache is a fallback, never an override.
|
|
23
|
+
*
|
|
24
|
+
* 3. Hot reload — ESM has no cache invalidation, so every project-local file
|
|
13
25
|
* URL carries a ?gen=N query. Bumping the generation makes the next
|
|
14
26
|
* import() re-evaluate the whole project module graph; the hook propagates
|
|
15
27
|
* the parent's generation to children so nothing stale survives a save.
|
|
@@ -17,12 +29,14 @@
|
|
|
17
29
|
* TypeScript runs through Node's native type stripping (>= 22.18 / 23.6).
|
|
18
30
|
*/
|
|
19
31
|
import { registerHooks } from 'node:module';
|
|
20
|
-
import { existsSync, statSync } from 'node:fs';
|
|
32
|
+
import { existsSync, realpathSync, statSync } from 'node:fs';
|
|
21
33
|
import { dirname, resolve as resolvePath } from 'node:path';
|
|
22
34
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
23
35
|
const EXT_CANDIDATES = ['.ts', '.tsx', '.mts', '.js', '.mjs', '.jsx'];
|
|
24
36
|
let generation = 1;
|
|
25
37
|
let installedRoot = null;
|
|
38
|
+
/** Extra dirs to resolve bare specifiers from, in order, after the project. */
|
|
39
|
+
let fallbackModuleDirs = [];
|
|
26
40
|
export function bumpGeneration() {
|
|
27
41
|
return ++generation;
|
|
28
42
|
}
|
|
@@ -38,7 +52,7 @@ export function assertNodeSupport() {
|
|
|
38
52
|
const [major, minor] = process.versions.node.split('.').map(Number);
|
|
39
53
|
const ok = major >= 24 || (major === 23 && minor >= 6) || (major === 22 && minor >= 18);
|
|
40
54
|
if (!ok) {
|
|
41
|
-
throw new Error(`somewhere dev
|
|
55
|
+
throw new Error(`somewhere dev needs Node >= 22.18 (or >= 23.6) for TypeScript support and module hooks — you're on ${process.versions.node}. Upgrade Node and retry.`);
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
function isFile(p) {
|
|
@@ -67,8 +81,27 @@ function resolveWithExtensions(base) {
|
|
|
67
81
|
* Install the resolve hook for project files under `projectRoot`.
|
|
68
82
|
* Safe to call once per process; subsequent calls just update the root.
|
|
69
83
|
*/
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Resolve symlinks. Node reports parentURL as a REAL path, so an installedRoot
|
|
86
|
+
* that still contains a symlink never prefix-matches it and the hook silently
|
|
87
|
+
* does nothing at all — no extensionless imports, no generation stamping, no
|
|
88
|
+
* dependency fallback. macOS makes this the DEFAULT for anything under /tmp
|
|
89
|
+
* (/tmp → /private/tmp, /var → /private/var), and a symlinked project
|
|
90
|
+
* directory does it anywhere.
|
|
91
|
+
*/
|
|
92
|
+
function realPath(p) {
|
|
93
|
+
try {
|
|
94
|
+
return realpathSync(p);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return p;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export function installLoader(projectRoot, moduleDirs = []) {
|
|
101
|
+
const root = realPath(resolvePath(projectRoot));
|
|
102
|
+
// Each entry is a node_modules dir; resolve from its PARENT so Node performs
|
|
103
|
+
// its normal node_modules lookup there.
|
|
104
|
+
fallbackModuleDirs = moduleDirs.map((dir) => realPath(resolvePath(dir, '..')));
|
|
72
105
|
if (installedRoot !== null) {
|
|
73
106
|
installedRoot = root;
|
|
74
107
|
return;
|
|
@@ -77,17 +110,45 @@ export function installLoader(projectRoot) {
|
|
|
77
110
|
registerHooks({
|
|
78
111
|
resolve(specifier, context, nextResolve) {
|
|
79
112
|
const parent = context.parentURL;
|
|
80
|
-
if (!installedRoot ||
|
|
81
|
-
!parent ||
|
|
82
|
-
!parent.startsWith('file://') ||
|
|
83
|
-
(!specifier.startsWith('./') && !specifier.startsWith('../'))) {
|
|
113
|
+
if (!installedRoot || !parent || !parent.startsWith('file://')) {
|
|
84
114
|
return nextResolve(specifier, context);
|
|
85
115
|
}
|
|
116
|
+
const isRelative = specifier.startsWith('./') || specifier.startsWith('../');
|
|
117
|
+
// A bare specifier: not relative, not root-anchored, not a URL scheme
|
|
118
|
+
// (node:, file:, data:, …).
|
|
119
|
+
const isBare = !isRelative
|
|
120
|
+
&& !specifier.startsWith('/')
|
|
121
|
+
&& !/^[a-z][a-z0-9+.-]*:/i.test(specifier);
|
|
122
|
+
if (!isRelative && !isBare)
|
|
123
|
+
return nextResolve(specifier, context);
|
|
86
124
|
const parentUrl = new URL(parent);
|
|
87
125
|
const parentPath = fileURLToPath(`file://${parentUrl.pathname}`);
|
|
88
126
|
if (!parentPath.startsWith(installedRoot)) {
|
|
89
127
|
return nextResolve(specifier, context);
|
|
90
128
|
}
|
|
129
|
+
if (isBare) {
|
|
130
|
+
try {
|
|
131
|
+
// The project's own node_modules first, always.
|
|
132
|
+
return nextResolve(specifier, context);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
if (err?.code !== 'ERR_MODULE_NOT_FOUND')
|
|
136
|
+
throw err;
|
|
137
|
+
for (const dir of fallbackModuleDirs) {
|
|
138
|
+
try {
|
|
139
|
+
return nextResolve(specifier, {
|
|
140
|
+
...context,
|
|
141
|
+
parentURL: pathToFileURL(resolvePath(dir, '__sw_resolve.js')).href,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (fallbackErr) {
|
|
145
|
+
if (fallbackErr?.code !== 'ERR_MODULE_NOT_FOUND')
|
|
146
|
+
throw fallbackErr;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
91
152
|
const target = resolvePath(dirname(parentPath), specifier);
|
|
92
153
|
const found = resolveWithExtensions(target);
|
|
93
154
|
if (!found) {
|
package/dist/local/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/local/loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/local/loader.ts"],"names":[],"mappings":"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"}
|