@somewhere-tech/cli 0.11.0 → 0.12.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/dist/commands/deploy.js +25 -5
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.js +70 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/exec.js +109 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/pull.js +8 -6
- package/dist/commands/pull.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/build-errors.js +147 -0
- package/dist/lib/build-errors.js.map +1 -0
- package/dist/lib/client.js +68 -4
- package/dist/lib/client.js.map +1 -1
- package/dist/local/envfile.js +40 -0
- package/dist/local/envfile.js.map +1 -0
- package/dist/local/loader.js +103 -0
- package/dist/local/loader.js.map +1 -0
- package/dist/local/router.js +114 -0
- package/dist/local/router.js.map +1 -0
- package/dist/local/runtime.js +268 -0
- package/dist/local/runtime.js.map +1 -0
- package/dist/local/server.js +169 -0
- package/dist/local/server.js.map +1 -0
- package/package.json +9 -4
- package/runtime/platform-context.mjs +3678 -0
- package/runtime/sw-init.mjs +237 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local function runtime behind `somewhere dev --local` and
|
|
3
|
+
* `somewhere exec`: run a project's functions in local Node while every
|
|
4
|
+
* sw.* binding talks to the real platform over the same REST surface the
|
|
5
|
+
* deployed runtime uses.
|
|
6
|
+
*
|
|
7
|
+
* Contract fidelity comes from running the VENDORED deployed runtime
|
|
8
|
+
* (runtime/platform-context.mjs + runtime/sw-init.mjs — extracted verbatim
|
|
9
|
+
* from the deploy pipeline) rather than a reimplementation. The deployed
|
|
10
|
+
* shim's REST fallback path (no D1 binding) is exactly the local path: we
|
|
11
|
+
* build the same `env` bindings object it expects, minus PROJECT_DB.
|
|
12
|
+
*
|
|
13
|
+
* Local-only deviations, all deliberate:
|
|
14
|
+
* - sw.env is a fail-loud proxy: keys that exist on the platform but have
|
|
15
|
+
* no local value THROW on access (the env API never returns values).
|
|
16
|
+
* - Handler errors return the real message + stack in the response body
|
|
17
|
+
* (deployed keeps them in logs only) — it's your own terminal.
|
|
18
|
+
* - Uncaught errors print to the terminal instead of POSTing to /v1/logs.
|
|
19
|
+
*/
|
|
20
|
+
import { readdirSync } from 'node:fs';
|
|
21
|
+
import { dirname, join, relative } from 'node:path';
|
|
22
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
23
|
+
import { IGNORE } from '../lib/files.js';
|
|
24
|
+
import { compileRoutes, matchRoute } from './router.js';
|
|
25
|
+
import { entryUrl } from './loader.js';
|
|
26
|
+
import { loadLocalEnv } from './envfile.js';
|
|
27
|
+
function packageRoot() {
|
|
28
|
+
// dist/local/runtime.js → package root is two levels up.
|
|
29
|
+
return join(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
30
|
+
}
|
|
31
|
+
let contextModule = null;
|
|
32
|
+
/** Import the vendored runtime once: sw-init (globalThis.sw.endpoint) + context factory. */
|
|
33
|
+
export async function loadVendoredRuntime() {
|
|
34
|
+
if (contextModule)
|
|
35
|
+
return contextModule;
|
|
36
|
+
const root = packageRoot();
|
|
37
|
+
await import(pathToFileURL(join(root, 'runtime', 'sw-init.mjs')).href);
|
|
38
|
+
contextModule = (await import(pathToFileURL(join(root, 'runtime', 'platform-context.mjs')).href));
|
|
39
|
+
return contextModule;
|
|
40
|
+
}
|
|
41
|
+
/** Walk the project dir and return every function-routable source file. */
|
|
42
|
+
export function collectFunctionFiles(cwd) {
|
|
43
|
+
const out = [];
|
|
44
|
+
const walk = (dir) => {
|
|
45
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
46
|
+
if (IGNORE.has(entry.name) || entry.name.startsWith('.'))
|
|
47
|
+
continue;
|
|
48
|
+
const full = join(dir, entry.name);
|
|
49
|
+
if (entry.isDirectory()) {
|
|
50
|
+
walk(full);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (!entry.isFile())
|
|
54
|
+
continue;
|
|
55
|
+
const rel = relative(cwd, full).split('\\').join('/');
|
|
56
|
+
if (!/\.(ts|tsx|mts|js|mjs|jsx)$/i.test(rel))
|
|
57
|
+
continue;
|
|
58
|
+
// Same key remapping as deploy: functions/ prefix is stripped; api/,
|
|
59
|
+
// _lib/ and root parametric files at the root are functions as-is.
|
|
60
|
+
const key = rel.startsWith('functions/') ? rel.slice('functions/'.length) : rel;
|
|
61
|
+
out.push({ file: key, absPath: full });
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
walk(cwd);
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Fetch everything the runtime needs from the platform (project info, env
|
|
69
|
+
* key list, table scopes), merge local env values, and compile routes.
|
|
70
|
+
*/
|
|
71
|
+
export async function prepareLocalProject(client, token, projectId, cwd) {
|
|
72
|
+
const [project, envResult, scopesResult] = await Promise.all([
|
|
73
|
+
client.call('GET', `/projects/${encodeURIComponent(projectId)}`),
|
|
74
|
+
client.call('GET', '/env', undefined, {
|
|
75
|
+
project_id: projectId,
|
|
76
|
+
}),
|
|
77
|
+
client
|
|
78
|
+
.call('GET', '/db/scopes', undefined, { project_id: projectId })
|
|
79
|
+
.catch(() => ({ scopes: [] })),
|
|
80
|
+
]);
|
|
81
|
+
const remoteKeys = (envResult.keys ?? envResult.vars ?? []).map((k) => k.key);
|
|
82
|
+
const localFileEnv = loadLocalEnv(cwd);
|
|
83
|
+
const values = {};
|
|
84
|
+
for (const key of remoteKeys) {
|
|
85
|
+
const local = localFileEnv[key] ?? process.env[key];
|
|
86
|
+
if (local !== undefined)
|
|
87
|
+
values[key] = local;
|
|
88
|
+
}
|
|
89
|
+
// Local-only keys are honored too — useful before the first `somewhere env set`.
|
|
90
|
+
for (const [key, value] of Object.entries(localFileEnv)) {
|
|
91
|
+
if (!(key in values))
|
|
92
|
+
values[key] = value;
|
|
93
|
+
}
|
|
94
|
+
const missingEnvKeys = remoteKeys.filter((k) => !(k in values));
|
|
95
|
+
const scopes = {};
|
|
96
|
+
for (const s of scopesResult.scopes ?? []) {
|
|
97
|
+
scopes[s.table.toLowerCase()] = s.owner_column;
|
|
98
|
+
}
|
|
99
|
+
// Mirror of the deploy pipeline's bindings (buildFunctionBundle), minus
|
|
100
|
+
// PROJECT_DB — its absence selects the runtime's REST db path, which is
|
|
101
|
+
// exactly what local dev wants.
|
|
102
|
+
const bindings = {
|
|
103
|
+
PROJECT_ID: project.id,
|
|
104
|
+
SUBDOMAIN: project.subdomain,
|
|
105
|
+
TIER: 'free', // tier isn't readable over the project API; only informational in the runtime
|
|
106
|
+
PROJECT_API_KEY: token,
|
|
107
|
+
USER_ENV: JSON.stringify(values),
|
|
108
|
+
PROJECT_SCOPES: JSON.stringify(scopes),
|
|
109
|
+
PROJECT_ENV: 'dev',
|
|
110
|
+
};
|
|
111
|
+
const files = collectFunctionFiles(cwd);
|
|
112
|
+
const routes = compileRoutes(files);
|
|
113
|
+
return {
|
|
114
|
+
projectId: project.id,
|
|
115
|
+
subdomain: project.subdomain,
|
|
116
|
+
cwd,
|
|
117
|
+
bindings,
|
|
118
|
+
missingEnvKeys,
|
|
119
|
+
localEnvKeys: Object.keys(values),
|
|
120
|
+
routes,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/** Re-scan the directory and recompile routes (after add/remove of files). */
|
|
124
|
+
export function refreshRoutes(state) {
|
|
125
|
+
state.routes = compileRoutes(collectFunctionFiles(state.cwd));
|
|
126
|
+
}
|
|
127
|
+
// ─── sw.env fail-loud proxy ─────────────────────────────────────────────────
|
|
128
|
+
function makeEnvProxy(values, missingKeys) {
|
|
129
|
+
const missing = new Set(missingKeys);
|
|
130
|
+
return new Proxy({ ...values }, {
|
|
131
|
+
get(target, prop, receiver) {
|
|
132
|
+
if (typeof prop !== 'string')
|
|
133
|
+
return Reflect.get(target, prop, receiver);
|
|
134
|
+
if (prop in target)
|
|
135
|
+
return target[prop];
|
|
136
|
+
if (missing.has(prop)) {
|
|
137
|
+
throw new Error(`sw.env.${prop} is set on the platform, but env values can't be fetched over the API. ` +
|
|
138
|
+
`Add ${prop}=... to a .env file in your project root (never deployed) or export it ` +
|
|
139
|
+
`in your shell, then restart \`somewhere dev --local\`.`);
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
},
|
|
143
|
+
has(target, prop) {
|
|
144
|
+
return Reflect.has(target, prop) || (typeof prop === 'string' && missing.has(prop));
|
|
145
|
+
},
|
|
146
|
+
ownKeys(target) {
|
|
147
|
+
return [...new Set([...Reflect.ownKeys(target), ...missing])];
|
|
148
|
+
},
|
|
149
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
150
|
+
const own = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
151
|
+
if (own)
|
|
152
|
+
return own;
|
|
153
|
+
if (typeof prop === 'string' && missing.has(prop)) {
|
|
154
|
+
return { enumerable: true, configurable: true, value: undefined };
|
|
155
|
+
}
|
|
156
|
+
return undefined;
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// ─── Dispatch (port of the generated index.mjs fetch handler) ───────────────
|
|
161
|
+
function jsonError(status, code, message) {
|
|
162
|
+
return new Response(JSON.stringify({ ok: false, error: code, message }), {
|
|
163
|
+
status,
|
|
164
|
+
headers: { 'Content-Type': 'application/json' },
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/** Port of the shim's attachPendingRefresh — auth auto-refresh headers + cookies. */
|
|
168
|
+
function attachPendingRefresh(response, ctx) {
|
|
169
|
+
const pending = ctx.__sw_pendingRefresh;
|
|
170
|
+
const cookies = ctx.__sw_pendingCookies ?? [];
|
|
171
|
+
const hasRefresh = !!(pending && pending.access && pending.refresh);
|
|
172
|
+
if (!hasRefresh && cookies.length === 0)
|
|
173
|
+
return response;
|
|
174
|
+
const headers = new Headers(response.headers);
|
|
175
|
+
if (hasRefresh && pending) {
|
|
176
|
+
headers.set('X-New-Access-Token', pending.access);
|
|
177
|
+
headers.set('X-New-Refresh-Token', pending.refresh);
|
|
178
|
+
}
|
|
179
|
+
for (const c of cookies)
|
|
180
|
+
headers.append('Set-Cookie', c);
|
|
181
|
+
return new Response(response.body, {
|
|
182
|
+
status: response.status,
|
|
183
|
+
statusText: response.statusText,
|
|
184
|
+
headers,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Route one Request through the local runtime: match → import (current
|
|
189
|
+
* generation) → buildPlatformContext → handler → response envelope.
|
|
190
|
+
*/
|
|
191
|
+
export async function dispatchRequest(request, state) {
|
|
192
|
+
const url = new URL(request.url);
|
|
193
|
+
const match = matchRoute(state.routes, url.pathname);
|
|
194
|
+
if (!match) {
|
|
195
|
+
return {
|
|
196
|
+
response: jsonError(404, 'FUNCTION_NOT_FOUND', 'No function registered at ' + url.pathname),
|
|
197
|
+
route: null,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
let mod;
|
|
201
|
+
try {
|
|
202
|
+
mod = (await import(entryUrl(match.route.absPath)));
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
response: jsonError(500, 'FUNCTION_LOAD_FAILED', `${match.route.file} failed to load: ${err instanceof Error ? err.message : String(err)}`),
|
|
207
|
+
route: match.route.displayPath,
|
|
208
|
+
error: err,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const method = request.method.toUpperCase();
|
|
212
|
+
const handler = (mod[method] ?? mod.default);
|
|
213
|
+
if (typeof handler !== 'function') {
|
|
214
|
+
return {
|
|
215
|
+
response: jsonError(405, 'METHOD_NOT_ALLOWED', method + ' not supported on ' + match.route.displayPath),
|
|
216
|
+
route: match.route.displayPath,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
Object.defineProperty(request, 'params', {
|
|
221
|
+
value: match.params,
|
|
222
|
+
enumerable: true,
|
|
223
|
+
configurable: true,
|
|
224
|
+
writable: true,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// frozen Request — sw.params still carries them
|
|
229
|
+
}
|
|
230
|
+
const { buildPlatformContext } = await loadVendoredRuntime();
|
|
231
|
+
let ctx;
|
|
232
|
+
try {
|
|
233
|
+
ctx = buildPlatformContext(state.bindings, request);
|
|
234
|
+
ctx.params = match.params;
|
|
235
|
+
// Swap the plain env object for the fail-loud proxy (see module docs).
|
|
236
|
+
ctx.env = makeEnvProxy(JSON.parse(state.bindings.USER_ENV || '{}'), state.missingEnvKeys);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
return {
|
|
240
|
+
response: jsonError(500, 'CONTEXT_BUILD_FAILED', `Function context could not be built: ${err instanceof Error ? err.message : String(err)}`),
|
|
241
|
+
route: match.route.displayPath,
|
|
242
|
+
error: err,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const result = await handler(request, ctx);
|
|
247
|
+
let response;
|
|
248
|
+
if (result instanceof Response) {
|
|
249
|
+
response = result;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
response = new Response(JSON.stringify(result), {
|
|
253
|
+
headers: { 'Content-Type': 'application/json' },
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return { response: attachPendingRefresh(response, ctx), route: match.route.displayPath };
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
// Deployed runtime hides the message and points at dashboard Logs; local
|
|
260
|
+
// dev puts the real error in the response — it's the developer's terminal.
|
|
261
|
+
return {
|
|
262
|
+
response: jsonError(500, 'FUNCTION_ERROR', `Function handler threw: ${err instanceof Error ? err.message : String(err)}`),
|
|
263
|
+
route: match.route.displayPath,
|
|
264
|
+
error: err,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/local/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server for `somewhere dev --local` — bridges Node's http server
|
|
3
|
+
* to the fetch-shaped dispatch in runtime.ts, with chokidar hot reload.
|
|
4
|
+
* Functions only: static files are the deploy/preview pipeline's job.
|
|
5
|
+
*/
|
|
6
|
+
import { createServer } from 'node:http';
|
|
7
|
+
import { Readable } from 'node:stream';
|
|
8
|
+
import { relative } from 'node:path';
|
|
9
|
+
import chokidar from 'chokidar';
|
|
10
|
+
import { IGNORE } from '../lib/files.js';
|
|
11
|
+
import { bold, dim, green, red, teal, warn, yellow } from '../lib/output.js';
|
|
12
|
+
import { bumpGeneration } from './loader.js';
|
|
13
|
+
import { dispatchRequest, refreshRoutes } from './runtime.js';
|
|
14
|
+
const RELOAD_EXTS = /\.(ts|tsx|mts|js|mjs|jsx|json)$/i;
|
|
15
|
+
async function toFetchRequest(req, port) {
|
|
16
|
+
const url = `http://localhost:${port}${req.url ?? '/'}`;
|
|
17
|
+
const method = (req.method ?? 'GET').toUpperCase();
|
|
18
|
+
const headers = new Headers();
|
|
19
|
+
for (const [k, v] of Object.entries(req.headers)) {
|
|
20
|
+
if (v === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
if (Array.isArray(v))
|
|
23
|
+
for (const item of v)
|
|
24
|
+
headers.append(k, item);
|
|
25
|
+
else
|
|
26
|
+
headers.set(k, v);
|
|
27
|
+
}
|
|
28
|
+
let body;
|
|
29
|
+
if (method !== 'GET' && method !== 'HEAD') {
|
|
30
|
+
const chunks = [];
|
|
31
|
+
for await (const chunk of req)
|
|
32
|
+
chunks.push(chunk);
|
|
33
|
+
body = Buffer.concat(chunks);
|
|
34
|
+
}
|
|
35
|
+
return new Request(url, { method, headers, body });
|
|
36
|
+
}
|
|
37
|
+
async function writeNodeResponse(response, res) {
|
|
38
|
+
const headers = {};
|
|
39
|
+
for (const [k, v] of response.headers.entries()) {
|
|
40
|
+
if (k.toLowerCase() === 'set-cookie')
|
|
41
|
+
continue;
|
|
42
|
+
headers[k] = v;
|
|
43
|
+
}
|
|
44
|
+
const cookies = response.headers.getSetCookie();
|
|
45
|
+
if (cookies.length)
|
|
46
|
+
headers['set-cookie'] = cookies;
|
|
47
|
+
res.writeHead(response.status, headers);
|
|
48
|
+
if (response.body) {
|
|
49
|
+
Readable.fromWeb(response.body).pipe(res);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
res.end();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function statusColor(status) {
|
|
56
|
+
if (status >= 500)
|
|
57
|
+
return red;
|
|
58
|
+
if (status >= 400)
|
|
59
|
+
return yellow;
|
|
60
|
+
return green;
|
|
61
|
+
}
|
|
62
|
+
function stamp() {
|
|
63
|
+
const d = new Date();
|
|
64
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
65
|
+
return `[${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}]`;
|
|
66
|
+
}
|
|
67
|
+
export function startLocalServer(state, opts) {
|
|
68
|
+
const { port } = opts;
|
|
69
|
+
const server = createServer((req, res) => {
|
|
70
|
+
void (async () => {
|
|
71
|
+
const t0 = Date.now();
|
|
72
|
+
let request;
|
|
73
|
+
try {
|
|
74
|
+
request = await toFetchRequest(req, port);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
78
|
+
res.end(JSON.stringify({ ok: false, error: 'BAD_REQUEST', message: String(err) }));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const result = await dispatchRequest(request, state);
|
|
82
|
+
const ms = Date.now() - t0;
|
|
83
|
+
const color = statusColor(result.response.status);
|
|
84
|
+
console.log(`${dim(stamp())} ${request.method} ${new URL(request.url).pathname} ${color(String(result.response.status))} ${dim(`${ms}ms`)}${result.route ? dim(` → ${result.route}`) : ''}`);
|
|
85
|
+
if (result.error) {
|
|
86
|
+
const err = result.error;
|
|
87
|
+
console.error(red(err instanceof Error ? err.stack ?? err.message : String(err)));
|
|
88
|
+
}
|
|
89
|
+
await writeNodeResponse(result.response, res);
|
|
90
|
+
})().catch((err) => {
|
|
91
|
+
console.error(red(`Internal local-server error: ${err instanceof Error ? err.stack ?? err.message : String(err)}`));
|
|
92
|
+
if (!res.headersSent) {
|
|
93
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
94
|
+
}
|
|
95
|
+
res.end(JSON.stringify({ ok: false, error: 'LOCAL_SERVER_ERROR', message: 'See terminal.' }));
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
server.listen(port, () => {
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log(`${green('▲')} ${bold('Local function runtime')} ${dim('— functions run here, sw.* talks to the real project')}`);
|
|
101
|
+
console.log(`${teal('🌐')} ${bold('Listening:')} ${teal(`http://localhost:${port}`)}`);
|
|
102
|
+
for (const r of state.routes) {
|
|
103
|
+
console.log(` ${dim('•')} ${r.displayPath} ${dim(`(${r.file})`)}`);
|
|
104
|
+
}
|
|
105
|
+
if (state.missingEnvKeys.length) {
|
|
106
|
+
warn(`Platform env keys with no local value (access will throw): ${state.missingEnvKeys.join(', ')}. ` +
|
|
107
|
+
'Add them to .env in this directory to use them locally.');
|
|
108
|
+
}
|
|
109
|
+
console.log(dim(' save a file to hot-reload. Ctrl-C to stop.\n'));
|
|
110
|
+
});
|
|
111
|
+
server.on('error', (err) => {
|
|
112
|
+
if (err.code === 'EADDRINUSE') {
|
|
113
|
+
console.error(red(`Port ${port} is already in use — pass --port <n> to pick another.`));
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
throw err;
|
|
117
|
+
});
|
|
118
|
+
// Hot reload: any source change bumps the module generation; add/remove
|
|
119
|
+
// also recompiles the route table.
|
|
120
|
+
let reloadTimer = null;
|
|
121
|
+
const scheduleReload = (rel, structural) => {
|
|
122
|
+
if (reloadTimer)
|
|
123
|
+
clearTimeout(reloadTimer);
|
|
124
|
+
reloadTimer = setTimeout(() => {
|
|
125
|
+
bumpGeneration();
|
|
126
|
+
if (structural) {
|
|
127
|
+
try {
|
|
128
|
+
refreshRoutes(state);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error(red(`Route compile failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
console.log(`${dim(stamp())} ${teal(rel)} ${dim('reloaded')}`);
|
|
136
|
+
}, 150);
|
|
137
|
+
};
|
|
138
|
+
const watcher = chokidar.watch(state.cwd, {
|
|
139
|
+
ignoreInitial: true,
|
|
140
|
+
ignored: (p) => {
|
|
141
|
+
const rel = relative(state.cwd, p);
|
|
142
|
+
if (!rel || rel.startsWith('..'))
|
|
143
|
+
return false;
|
|
144
|
+
return rel
|
|
145
|
+
.split(/[\\/]/)
|
|
146
|
+
.some((seg) => IGNORE.has(seg) || (seg.startsWith('.') && seg !== '.' && seg !== ''));
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
watcher.on('change', (abs) => {
|
|
150
|
+
const rel = relative(state.cwd, abs);
|
|
151
|
+
if (RELOAD_EXTS.test(rel))
|
|
152
|
+
scheduleReload(rel, false);
|
|
153
|
+
});
|
|
154
|
+
watcher.on('add', (abs) => {
|
|
155
|
+
const rel = relative(state.cwd, abs);
|
|
156
|
+
if (RELOAD_EXTS.test(rel))
|
|
157
|
+
scheduleReload(rel, true);
|
|
158
|
+
});
|
|
159
|
+
watcher.on('unlink', (abs) => {
|
|
160
|
+
const rel = relative(state.cwd, abs);
|
|
161
|
+
if (RELOAD_EXTS.test(rel))
|
|
162
|
+
scheduleReload(rel, true);
|
|
163
|
+
});
|
|
164
|
+
process.on('SIGINT', () => {
|
|
165
|
+
console.log(`\n${dim('Stopped.')}`);
|
|
166
|
+
watcher.close().finally(() => process.exit(0));
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/local/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@somewhere-tech/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "CLI for somewhere.tech — auth, projects, deploy, pull, promote, db, logs, env, MCP bridge.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"somewhere",
|
|
@@ -27,13 +27,17 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"bin",
|
|
29
29
|
"dist",
|
|
30
|
+
"runtime",
|
|
30
31
|
"README.md",
|
|
31
32
|
"LICENSE"
|
|
32
33
|
],
|
|
33
34
|
"scripts": {
|
|
34
35
|
"build": "tsc",
|
|
35
36
|
"dev": "tsc --watch",
|
|
36
|
-
"prepublishOnly": "npm run build"
|
|
37
|
+
"prepublishOnly": "npm run build",
|
|
38
|
+
"test": "npm run build && node --test \"test/*.test.mjs\"",
|
|
39
|
+
"test:roundtrip": "node scripts/e2e-roundtrip.mjs",
|
|
40
|
+
"test:e2e-local": "node scripts/e2e-local.mjs"
|
|
37
41
|
},
|
|
38
42
|
"engines": {
|
|
39
43
|
"node": ">=18"
|
|
@@ -45,10 +49,11 @@
|
|
|
45
49
|
"commander": "^12.0.0",
|
|
46
50
|
"open": "^10.0.0",
|
|
47
51
|
"ora": "^8.0.0",
|
|
48
|
-
"prompts": "^2.4.2"
|
|
52
|
+
"prompts": "^2.4.2",
|
|
53
|
+
"undici": "^8.4.1"
|
|
49
54
|
},
|
|
50
55
|
"devDependencies": {
|
|
51
|
-
"@types/node": "^
|
|
56
|
+
"@types/node": "^22.19.21",
|
|
52
57
|
"@types/prompts": "^2.4.0",
|
|
53
58
|
"typescript": "^5.4.0"
|
|
54
59
|
}
|