@lensmcp/cluster 1.18.4 → 1.18.7
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/basic-ssl.js +1 -241
- package/build-scope-patterns.js +1 -40
- package/create-webpack-dev.js +1 -186
- package/create-webpack-prod.js +1 -169
- package/executors/build/build.impl.js +1 -98
- package/executors/gateway/gateway-errors.js +1 -43
- package/executors/gateway/gateway.impl.js +1 -53
- package/executors/gateway/gateway.lib.js +1 -29
- package/executors/gateway/health-check.js +1 -66
- package/executors/gateway/jwks-verify.js +1 -121
- package/executors/gateway/main.prod-gateway.js +2 -573
- package/executors/gateway/main.rollout.js +11 -117
- package/executors/gateway/manifest.js +1 -374
- package/executors/gateway/metrics.js +1 -56
- package/executors/gateway/otel-tracing.js +1 -74
- package/executors/gateway/prod-gateway.lib.js +1 -22
- package/executors/gateway/prod-runtime/access-log.js +1 -24
- package/executors/gateway/prod-runtime/app.js +1 -123
- package/executors/gateway/prod-runtime/auth.js +1 -51
- package/executors/gateway/prod-runtime/cors.js +1 -40
- package/executors/gateway/prod-runtime/edge.js +1 -65
- package/executors/gateway/prod-runtime/handler.js +1 -226
- package/executors/gateway/prod-runtime/hooks.js +1 -42
- package/executors/gateway/prod-runtime/observability.js +1 -125
- package/executors/gateway/prod-runtime/rollout.js +1 -103
- package/executors/gateway/prod-runtime/routing.js +1 -40
- package/executors/gateway/prod-runtime/server.js +1 -79
- package/executors/gateway/prod-runtime/trust.js +1 -32
- package/executors/gateway/prod-runtime/types.js +1 -2
- package/executors/gateway/prod-runtime/upgrade.js +4 -116
- package/executors/gateway/prod-runtime/upstream.js +1 -21
- package/executors/gateway/providers-prod.js +1 -232
- package/executors/gateway/rate-limit.js +2 -75
- package/executors/gateway/registry-source.js +1 -131
- package/executors/gateway/rollout-ops.js +2 -167
- package/executors/gateway/runtime/auth.js +1 -64
- package/executors/gateway/runtime/chooser.js +12 -45
- package/executors/gateway/runtime/control.js +1 -128
- package/executors/gateway/runtime/dev-auth.js +1 -108
- package/executors/gateway/runtime/discovery.js +1 -123
- package/executors/gateway/runtime/edge.js +1 -47
- package/executors/gateway/runtime/handler.js +1 -183
- package/executors/gateway/runtime/hooks.js +1 -55
- package/executors/gateway/runtime/lens-children.js +1 -651
- package/executors/gateway/runtime/lifecycle.js +3 -842
- package/executors/gateway/runtime/observability.js +2 -148
- package/executors/gateway/runtime/pod-env.js +2 -89
- package/executors/gateway/runtime/proxy.js +1 -457
- package/executors/gateway/runtime/route-registry.js +1 -72
- package/executors/gateway/runtime/scope.js +1 -117
- package/executors/gateway/runtime/server.js +3 -487
- package/executors/gateway/runtime/service-keys.js +1 -49
- package/executors/gateway/runtime/types.js +1 -151
- package/executors/gateway/runtime/upgrade.js +1 -71
- package/executors/gateway/runtime/workspace-registry.js +1 -99
- package/executors/gateway/ssrf-guard.js +1 -190
- package/executors/serve/serve.impl.js +1 -280
- package/executors/trust/trust.impl.js +4 -162
- package/gateway.js +1 -35
- package/index.js +1 -16
- package/main.devserver.js +10 -1117
- package/package.json +4 -3
- package/tsgo-check-plugin.js +4 -364
- package/typecheck-bus.js +4 -256
package/basic-ssl.js
CHANGED
|
@@ -1,241 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CA_CERT_FILE = void 0;
|
|
4
|
-
exports.caDir = caDir;
|
|
5
|
-
exports.caCertPath = caCertPath;
|
|
6
|
-
exports.getCertificateSync = getCertificateSync;
|
|
7
|
-
exports.ensureCaSync = ensureCaSync;
|
|
8
|
-
const tslib_1 = require("tslib");
|
|
9
|
-
/**
|
|
10
|
-
* Dev HTTPS certificates, mkcert-style: a long-lived LOCAL CA (10 years,
|
|
11
|
-
* minted once per MACHINE, trusted once in the OS keychain) signs short-lived
|
|
12
|
-
* leaf certs (30 days, re-minted per SAN set). Because the browser chains the
|
|
13
|
-
* leaf to the trusted CA, cert rotation and new gateway hostnames never show
|
|
14
|
-
* an interstitial again — unlike a bare self-signed cert, which would need
|
|
15
|
-
* re-trusting on every change.
|
|
16
|
-
*
|
|
17
|
-
* The CA is MACHINE-LEVEL — `~/.lensmcp/ca/` (override the home via
|
|
18
|
-
* `LENSMCP_HOME`, same convention as the workspace registry) — so every
|
|
19
|
-
* workspace/daemon on the machine serves chains anchored to ONE CA:
|
|
20
|
-
* - the OS keychain holds exactly one "lensmcp local dev CA" (no same-CN
|
|
21
|
-
* collisions between per-workspace CAs shadowing each other in `trust`),
|
|
22
|
-
* - a pod's `NODE_EXTRA_CA_CERTS` stays valid across daemon handovers
|
|
23
|
-
* (guest workspace → own daemon), because every daemon signs with the
|
|
24
|
-
* same anchor.
|
|
25
|
-
* The first machine-CA resolution PROMOTES a pre-existing per-workspace CA
|
|
26
|
-
* (the pre-machine-CA layout) when one exists, so keychain trust already
|
|
27
|
-
* granted to it carries over without another sudo prompt. LEAF certs stay
|
|
28
|
-
* per-workspace in `<root>/node_modules/.cache/davnx-webpack` and are reused
|
|
29
|
-
* only when they chain to the CURRENT machine CA (the issuer pin below).
|
|
30
|
-
*
|
|
31
|
-
* `getCertificateSync` returns ONE concatenated PEM (leaf key + leaf cert +
|
|
32
|
-
* CA cert). Node's `https.createServer({ key: pem, cert: pem })` accepts it:
|
|
33
|
-
* `key` takes the first private-key block, `cert` takes every certificate
|
|
34
|
-
* block (leaf first, then the CA as the served chain).
|
|
35
|
-
*
|
|
36
|
-
* Trust once (macOS):
|
|
37
|
-
* sudo security add-trusted-cert -d -r trustRoot \
|
|
38
|
-
* -k /Library/Keychains/System.keychain ~/.lensmcp/ca/lensmcp-local-ca.crt
|
|
39
|
-
*/
|
|
40
|
-
const crypto = tslib_1.__importStar(require("node:crypto"));
|
|
41
|
-
const fs = tslib_1.__importStar(require("node:fs"));
|
|
42
|
-
const os = tslib_1.__importStar(require("node:os"));
|
|
43
|
-
const path = tslib_1.__importStar(require("node:path"));
|
|
44
|
-
/** Re-mint the leaf when the cached one is older than this (TTL is 30 days). */
|
|
45
|
-
const LEAF_MAX_AGE_MS = 25 * 24 * 60 * 60 * 1000;
|
|
46
|
-
/** CA lifetime (~10 years) and the remaining-validity floor for reuse. */
|
|
47
|
-
const CA_TTL_DAYS = 3650;
|
|
48
|
-
const CA_MIN_REMAINING_MS = 30 * 24 * 60 * 60 * 1000;
|
|
49
|
-
exports.CA_CERT_FILE = 'lensmcp-local-ca.crt';
|
|
50
|
-
/** The legacy (pre-rebrand) CA filename — swept on mint so a stale `davnx-local-ca.crt` never lingers. */
|
|
51
|
-
const LEGACY_CA_CERT_FILE = 'davnx-local-ca.crt';
|
|
52
|
-
const CA_KEY_FILE = '_ca-key.pem';
|
|
53
|
-
/** The machine-level CA directory: `~/.lensmcp/ca` (override home via `LENSMCP_HOME` — tests). */
|
|
54
|
-
function caDir() {
|
|
55
|
-
const home = process.env['LENSMCP_HOME'] || os.homedir();
|
|
56
|
-
return path.join(home, '.lensmcp', 'ca');
|
|
57
|
-
}
|
|
58
|
-
/** Absolute path of the trust-once, machine-level CA certificate. */
|
|
59
|
-
function caCertPath() {
|
|
60
|
-
return path.join(caDir(), exports.CA_CERT_FILE);
|
|
61
|
-
}
|
|
62
|
-
function getCertificateSync(cacheDir, name = 'lensmcp.dev', domains = []) {
|
|
63
|
-
// Resolve the CA FIRST (machine-level; promotes this workspace's legacy CA on first touch). The current
|
|
64
|
-
// CA pem then gates the leaf cache below — an issuer pin, see there.
|
|
65
|
-
const forge = require('node-forge');
|
|
66
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
67
|
-
const ca = loadOrCreateCa(forge, cacheDir);
|
|
68
|
-
const caPem = forge.pki.certificateToPem(ca.cert);
|
|
69
|
-
// The SAN set is part of the cache key: adding a gateway hostname must
|
|
70
|
-
// mint a fresh leaf, not serve a cached one that lacks the new SAN.
|
|
71
|
-
const sanKey = crypto
|
|
72
|
-
.createHash('sha256')
|
|
73
|
-
.update([name, ...[...domains].sort()].join('|'))
|
|
74
|
-
.digest('hex')
|
|
75
|
-
.slice(0, 12);
|
|
76
|
-
const leafPath = path.join(cacheDir, `_leaf-${sanKey}.pem`);
|
|
77
|
-
try {
|
|
78
|
-
const stat = fs.statSync(leafPath);
|
|
79
|
-
if (Date.now() - stat.ctimeMs < LEAF_MAX_AGE_MS) {
|
|
80
|
-
const cached = fs.readFileSync(leafPath, 'utf8');
|
|
81
|
-
// ISSUER PIN: the cached pem embeds the CA it chained to — serve it only when that is the CURRENT
|
|
82
|
-
// machine CA. With the CA machine-level, a stale leaf in THIS workspace can't be swept by a CA mint
|
|
83
|
-
// that happened elsewhere (another workspace, or pre-machine-CA code), so the old "a mint sweeps
|
|
84
|
-
// this dir's leaves" guarantee no longer covers every path; the pin does.
|
|
85
|
-
if (cached.includes(caPem))
|
|
86
|
-
return cached;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
/* no cache yet */
|
|
91
|
-
}
|
|
92
|
-
const pem = createLeafCertificate(forge, ca, name, domains);
|
|
93
|
-
fs.writeFileSync(leafPath, pem);
|
|
94
|
-
// Stale leaves and the pre-1.3.4 self-signed cache just rot here — sweep
|
|
95
|
-
// them so the dir holds only the active leaf (+ any legacy CA pair, kept
|
|
96
|
-
// readable for older-code daemons that still anchor to it).
|
|
97
|
-
for (const f of fs.readdirSync(cacheDir)) {
|
|
98
|
-
const stale = (/^_leaf-.*\.pem$/.test(f) && f !== `_leaf-${sanKey}.pem`) ||
|
|
99
|
-
/^_cert.*\.pem$/.test(f) ||
|
|
100
|
-
/-dev\.crt$/.test(f) ||
|
|
101
|
-
f === LEGACY_CA_CERT_FILE;
|
|
102
|
-
if (stale) {
|
|
103
|
-
try {
|
|
104
|
-
fs.unlinkSync(path.join(cacheDir, f));
|
|
105
|
-
}
|
|
106
|
-
catch { /* best effort */ }
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return pem;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Ensure the machine-level CA exists (promoting `legacyCacheDir`'s per-workspace
|
|
113
|
-
* CA when the machine store is still empty); returns the machine CA cert path.
|
|
114
|
-
*/
|
|
115
|
-
function ensureCaSync(legacyCacheDir) {
|
|
116
|
-
const forge = require('node-forge');
|
|
117
|
-
loadOrCreateCa(forge, legacyCacheDir);
|
|
118
|
-
return caCertPath();
|
|
119
|
-
}
|
|
120
|
-
/** Read a CA pair from `dir`; undefined when absent, unreadable, or too close to expiry to reuse. */
|
|
121
|
-
function readCaPair(dir, forge) {
|
|
122
|
-
try {
|
|
123
|
-
const cert = forge.pki.certificateFromPem(fs.readFileSync(path.join(dir, exports.CA_CERT_FILE), 'utf8'));
|
|
124
|
-
const key = forge.pki.privateKeyFromPem(fs.readFileSync(path.join(dir, CA_KEY_FILE), 'utf8'));
|
|
125
|
-
if (cert.validity.notAfter.getTime() - Date.now() > CA_MIN_REMAINING_MS) {
|
|
126
|
-
return { cert, key };
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
/* absent or unreadable */
|
|
131
|
-
}
|
|
132
|
-
return undefined;
|
|
133
|
-
}
|
|
134
|
-
function loadOrCreateCa(forge, promoteFromDir) {
|
|
135
|
-
const dir = caDir();
|
|
136
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
137
|
-
const existing = readCaPair(dir, forge);
|
|
138
|
-
if (existing)
|
|
139
|
-
return existing;
|
|
140
|
-
// Files present but unusable (expired / half-written) — clear them so the `wx` claim below can win.
|
|
141
|
-
// Rotation this races is a once-per-decade event; last write wins is fine at dev grade.
|
|
142
|
-
for (const f of [CA_KEY_FILE, exports.CA_CERT_FILE]) {
|
|
143
|
-
try {
|
|
144
|
-
fs.unlinkSync(path.join(dir, f));
|
|
145
|
-
}
|
|
146
|
-
catch { /* absent */ }
|
|
147
|
-
}
|
|
148
|
-
// Candidate pair: PROMOTE the pre-machine-CA workspace pair when one exists — the exact cert the user
|
|
149
|
-
// already trusted in the keychain simply becomes the machine CA (no new sudo prompt). The workspace copy
|
|
150
|
-
// stays in place for any older-code daemon still anchoring to it. Otherwise mint fresh.
|
|
151
|
-
const promoted = promoteFromDir && promoteFromDir !== dir ? readCaPair(promoteFromDir, forge) : undefined;
|
|
152
|
-
const pair = promoted ?? mintCa(forge);
|
|
153
|
-
// Atomic claim on the KEY file (`wx`): concurrent daemons can race the first-ever machine resolution;
|
|
154
|
-
// exactly one pair may land on disk. The winner writes the cert right after; a loser adopts the winner's
|
|
155
|
-
// pair (bounded wait for that cert write).
|
|
156
|
-
try {
|
|
157
|
-
fs.writeFileSync(path.join(dir, CA_KEY_FILE), forge.pki.privateKeyToPem(pair.key), { mode: 0o600, flag: 'wx' });
|
|
158
|
-
}
|
|
159
|
-
catch (e) {
|
|
160
|
-
if (e.code !== 'EEXIST')
|
|
161
|
-
throw e;
|
|
162
|
-
const winner = spinReadCaPair(dir, forge);
|
|
163
|
-
if (winner)
|
|
164
|
-
return winner;
|
|
165
|
-
throw new Error(`machine dev CA at ${dir} is claimed but unreadable — remove the directory and retry`, { cause: e });
|
|
166
|
-
}
|
|
167
|
-
fs.writeFileSync(path.join(dir, exports.CA_CERT_FILE), forge.pki.certificateToPem(pair.cert));
|
|
168
|
-
if (promoted) {
|
|
169
|
-
console.log(`[ssl] promoted the existing workspace dev CA to the machine store (${dir}) — keychain trust carries over.`);
|
|
170
|
-
}
|
|
171
|
-
return pair;
|
|
172
|
-
}
|
|
173
|
-
/** Bounded sync wait for a concurrent claimer's cert write to land (claim→cert is two writes apart). */
|
|
174
|
-
function spinReadCaPair(dir, forge) {
|
|
175
|
-
const deadline = Date.now() + 2000;
|
|
176
|
-
for (;;) {
|
|
177
|
-
const pair = readCaPair(dir, forge);
|
|
178
|
-
if (pair || Date.now() >= deadline)
|
|
179
|
-
return pair;
|
|
180
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 25); // sync 25ms sleep
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
function mintCa(forge) {
|
|
184
|
-
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
185
|
-
const cert = forge.pki.createCertificate();
|
|
186
|
-
cert.publicKey = keys.publicKey;
|
|
187
|
-
cert.serialNumber = `00${Date.now().toString(16)}`;
|
|
188
|
-
cert.validity.notBefore = new Date(Date.now() - 24 * 60 * 60 * 1000); // clock-skew slack
|
|
189
|
-
cert.validity.notAfter = new Date();
|
|
190
|
-
cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + CA_TTL_DAYS);
|
|
191
|
-
const attrs = [
|
|
192
|
-
{ name: 'commonName', value: 'lensmcp local dev CA' },
|
|
193
|
-
{ name: 'organizationName', value: 'lensmcp' },
|
|
194
|
-
{ shortName: 'OU', value: 'dev' },
|
|
195
|
-
];
|
|
196
|
-
cert.setSubject(attrs);
|
|
197
|
-
cert.setIssuer(attrs);
|
|
198
|
-
cert.setExtensions([
|
|
199
|
-
{ name: 'basicConstraints', cA: true, critical: true },
|
|
200
|
-
{ name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
|
|
201
|
-
{ name: 'subjectKeyIdentifier' },
|
|
202
|
-
]);
|
|
203
|
-
cert.sign(keys.privateKey, forge.md.sha256.create());
|
|
204
|
-
return { cert, key: keys.privateKey };
|
|
205
|
-
}
|
|
206
|
-
function createLeafCertificate(forge, ca, name, domains, ttlDays = 30) {
|
|
207
|
-
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
208
|
-
const cert = forge.pki.createCertificate();
|
|
209
|
-
cert.publicKey = keys.publicKey;
|
|
210
|
-
cert.serialNumber = `00${Date.now().toString(16)}`;
|
|
211
|
-
cert.validity.notBefore = new Date(Date.now() - 24 * 60 * 60 * 1000); // clock-skew slack
|
|
212
|
-
cert.validity.notAfter = new Date();
|
|
213
|
-
cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + ttlDays);
|
|
214
|
-
cert.setSubject([
|
|
215
|
-
{ name: 'commonName', value: name },
|
|
216
|
-
{ name: 'organizationName', value: 'lensmcp' },
|
|
217
|
-
{ shortName: 'OU', value: 'dev' },
|
|
218
|
-
]);
|
|
219
|
-
cert.setIssuer(ca.cert.subject.attributes);
|
|
220
|
-
// SANs: localhost + loopbacks always; the gateway hostnames (incl. wildcards) on top.
|
|
221
|
-
const altNames = [
|
|
222
|
-
{ type: 2, value: 'localhost' },
|
|
223
|
-
{ type: 2, value: '*.localhost' },
|
|
224
|
-
{ type: 7, ip: '127.0.0.1' },
|
|
225
|
-
{ type: 7, ip: '::1' },
|
|
226
|
-
...[...new Set(domains)].filter((d) => d && d !== 'localhost').map((d) => ({ type: 2, value: d })),
|
|
227
|
-
];
|
|
228
|
-
// Apple/Chrome policy for leaf certs: SAN required, EKU serverAuth required,
|
|
229
|
-
// and a leaf must NOT be a CA — keyUsage stays signature/encipherment only.
|
|
230
|
-
cert.setExtensions([
|
|
231
|
-
{ name: 'basicConstraints', cA: false },
|
|
232
|
-
{ name: 'keyUsage', digitalSignature: true, keyEncipherment: true, critical: true },
|
|
233
|
-
{ name: 'extKeyUsage', serverAuth: true, clientAuth: true },
|
|
234
|
-
{ name: 'subjectAltName', altNames },
|
|
235
|
-
{ name: 'subjectKeyIdentifier' },
|
|
236
|
-
]);
|
|
237
|
-
cert.sign(ca.key, forge.md.sha256.create());
|
|
238
|
-
return (forge.pki.privateKeyToPem(keys.privateKey) +
|
|
239
|
-
forge.pki.certificateToPem(cert) +
|
|
240
|
-
forge.pki.certificateToPem(ca.cert));
|
|
241
|
-
}
|
|
1
|
+
"use strict";var f=Object.defineProperty;var c=(e,r)=>f(e,"name",{value:r,configurable:!0});var p=Object.defineProperty,a=c((e,r)=>p(e,"name",{value:r,configurable:!0}),"a");Object.defineProperty(exports,"__esModule",{value:!0}),exports.CA_CERT_FILE=void 0,exports.caDir=caDir,exports.caCertPath=caCertPath,exports.getCertificateSync=getCertificateSync,exports.ensureCaSync=ensureCaSync;const tslib_1=require("tslib"),crypto=tslib_1.__importStar(require("node:crypto")),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),LEAF_MAX_AGE_MS=600*60*60*1e3,CA_TTL_DAYS=3650,CA_MIN_REMAINING_MS=720*60*60*1e3;exports.CA_CERT_FILE="lensmcp-local-ca.crt";const LEGACY_CA_CERT_FILE="davnx-local-ca.crt",CA_KEY_FILE="_ca-key.pem";function caDir(){const e=process.env.LENSMCP_HOME||os.homedir();return path.join(e,".lensmcp","ca")}c(caDir,"caDir"),a(caDir,"caDir");function caCertPath(){return path.join(caDir(),exports.CA_CERT_FILE)}c(caCertPath,"caCertPath"),a(caCertPath,"caCertPath");function getCertificateSync(e,r="lensmcp.dev",t=[]){const n=require("node-forge");fs.mkdirSync(e,{recursive:!0});const l=loadOrCreateCa(n,e),o=n.pki.certificateToPem(l.cert),i=crypto.createHash("sha256").update([r,...[...t].sort()].join("|")).digest("hex").slice(0,12),s=path.join(e,`_leaf-${i}.pem`);try{const u=fs.statSync(s);if(Date.now()-u.ctimeMs<LEAF_MAX_AGE_MS){const m=fs.readFileSync(s,"utf8");if(m.includes(o))return m}}catch{}const y=createLeafCertificate(n,l,r,t);fs.writeFileSync(s,y);for(const u of fs.readdirSync(e))if(/^_leaf-.*\.pem$/.test(u)&&u!==`_leaf-${i}.pem`||/^_cert.*\.pem$/.test(u)||/-dev\.crt$/.test(u)||u===LEGACY_CA_CERT_FILE)try{fs.unlinkSync(path.join(e,u))}catch{}return y}c(getCertificateSync,"getCertificateSync"),a(getCertificateSync,"getCertificateSync");function ensureCaSync(e){const r=require("node-forge");return loadOrCreateCa(r,e),caCertPath()}c(ensureCaSync,"ensureCaSync"),a(ensureCaSync,"ensureCaSync");function readCaPair(e,r){try{const t=r.pki.certificateFromPem(fs.readFileSync(path.join(e,exports.CA_CERT_FILE),"utf8")),n=r.pki.privateKeyFromPem(fs.readFileSync(path.join(e,CA_KEY_FILE),"utf8"));if(t.validity.notAfter.getTime()-Date.now()>CA_MIN_REMAINING_MS)return{cert:t,key:n}}catch{}}c(readCaPair,"readCaPair"),a(readCaPair,"readCaPair");function loadOrCreateCa(e,r){const t=caDir();fs.mkdirSync(t,{recursive:!0});const n=readCaPair(t,e);if(n)return n;for(const i of[CA_KEY_FILE,exports.CA_CERT_FILE])try{fs.unlinkSync(path.join(t,i))}catch{}const l=r&&r!==t?readCaPair(r,e):void 0,o=l??mintCa(e);try{fs.writeFileSync(path.join(t,CA_KEY_FILE),e.pki.privateKeyToPem(o.key),{mode:384,flag:"wx"})}catch(i){if(i.code!=="EEXIST")throw i;const s=spinReadCaPair(t,e);if(s)return s;throw new Error(`machine dev CA at ${t} is claimed but unreadable \u2014 remove the directory and retry`,{cause:i})}return fs.writeFileSync(path.join(t,exports.CA_CERT_FILE),e.pki.certificateToPem(o.cert)),l&&console.log(`[ssl] promoted the existing workspace dev CA to the machine store (${t}) \u2014 keychain trust carries over.`),o}c(loadOrCreateCa,"loadOrCreateCa"),a(loadOrCreateCa,"loadOrCreateCa");function spinReadCaPair(e,r){const t=Date.now()+2e3;for(;;){const n=readCaPair(e,r);if(n||Date.now()>=t)return n;Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,25)}}c(spinReadCaPair,"spinReadCaPair"),a(spinReadCaPair,"spinReadCaPair");function mintCa(e){const r=e.pki.rsa.generateKeyPair(2048),t=e.pki.createCertificate();t.publicKey=r.publicKey,t.serialNumber=`00${Date.now().toString(16)}`,t.validity.notBefore=new Date(Date.now()-1440*60*1e3),t.validity.notAfter=new Date,t.validity.notAfter.setDate(t.validity.notAfter.getDate()+CA_TTL_DAYS);const n=[{name:"commonName",value:"lensmcp local dev CA"},{name:"organizationName",value:"lensmcp"},{shortName:"OU",value:"dev"}];return t.setSubject(n),t.setIssuer(n),t.setExtensions([{name:"basicConstraints",cA:!0,critical:!0},{name:"keyUsage",keyCertSign:!0,cRLSign:!0,critical:!0},{name:"subjectKeyIdentifier"}]),t.sign(r.privateKey,e.md.sha256.create()),{cert:t,key:r.privateKey}}c(mintCa,"mintCa"),a(mintCa,"mintCa");function createLeafCertificate(e,r,t,n,l=30){const o=e.pki.rsa.generateKeyPair(2048),i=e.pki.createCertificate();i.publicKey=o.publicKey,i.serialNumber=`00${Date.now().toString(16)}`,i.validity.notBefore=new Date(Date.now()-1440*60*1e3),i.validity.notAfter=new Date,i.validity.notAfter.setDate(i.validity.notAfter.getDate()+l),i.setSubject([{name:"commonName",value:t},{name:"organizationName",value:"lensmcp"},{shortName:"OU",value:"dev"}]),i.setIssuer(r.cert.subject.attributes);const s=[{type:2,value:"localhost"},{type:2,value:"*.localhost"},{type:7,ip:"127.0.0.1"},{type:7,ip:"::1"},...[...new Set(n)].filter(y=>y&&y!=="localhost").map(y=>({type:2,value:y}))];return i.setExtensions([{name:"basicConstraints",cA:!1},{name:"keyUsage",digitalSignature:!0,keyEncipherment:!0,critical:!0},{name:"extKeyUsage",serverAuth:!0,clientAuth:!0},{name:"subjectAltName",altNames:s},{name:"subjectKeyIdentifier"}]),i.sign(r.key,e.md.sha256.create()),e.pki.privateKeyToPem(o.privateKey)+e.pki.certificateToPem(i)+e.pki.certificateToPem(r.cert)}c(createLeafCertificate,"createLeafCertificate"),a(createLeafCertificate,"createLeafCertificate");
|
package/build-scope-patterns.js
CHANGED
|
@@ -1,40 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildScopePatterns = buildScopePatterns;
|
|
4
|
-
function buildScopePatterns(orgScopes) {
|
|
5
|
-
const allowlistPatterns = [];
|
|
6
|
-
const scopePrefixes = [];
|
|
7
|
-
const scopePatterns = [];
|
|
8
|
-
for (const scope of orgScopes) {
|
|
9
|
-
if (!scope)
|
|
10
|
-
continue;
|
|
11
|
-
const regexMatch = scope.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
12
|
-
if (regexMatch) {
|
|
13
|
-
// Regex: /pattern/flags — strip 'g' flag to avoid stateful lastIndex in .test()
|
|
14
|
-
const flags = regexMatch[2].replace('g', '');
|
|
15
|
-
const regex = new RegExp(regexMatch[1], flags);
|
|
16
|
-
allowlistPatterns.push(regex);
|
|
17
|
-
scopePatterns.push(regex);
|
|
18
|
-
}
|
|
19
|
-
else if (scope.includes('/')) {
|
|
20
|
-
// Prefix: @frontegg/agenshield → matches @frontegg/agenshield*
|
|
21
|
-
const escaped = scope.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
22
|
-
allowlistPatterns.push(new RegExp(`^${escaped}`));
|
|
23
|
-
scopePrefixes.push(scope);
|
|
24
|
-
}
|
|
25
|
-
else if (scope.startsWith('@')) {
|
|
26
|
-
// Org scope: @myorg → matches @myorg/*
|
|
27
|
-
const escaped = scope.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
28
|
-
allowlistPatterns.push(new RegExp(`^${escaped}/`));
|
|
29
|
-
scopePrefixes.push(scope.endsWith('/') ? scope : `${scope}/`);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// Exact package name: lodash → matches lodash and lodash/subpath
|
|
33
|
-
const escaped = scope.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
34
|
-
const regex = new RegExp(`^${escaped}(/|$)`);
|
|
35
|
-
allowlistPatterns.push(regex);
|
|
36
|
-
scopePatterns.push(regex);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return { allowlistPatterns, scopePrefixes, scopePatterns };
|
|
40
|
-
}
|
|
1
|
+
"use strict";var l=Object.defineProperty;var i=(n,s)=>l(n,"name",{value:s,configurable:!0});var a=Object.defineProperty,u=i((n,s)=>a(n,"name",{value:s,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildScopePatterns=buildScopePatterns;function buildScopePatterns(n){const s=[],p=[],r=[];for(const e of n){if(!e)continue;const o=e.match(/^\/(.+)\/([gimsuy]*)$/);if(o){const t=o[2].replace("g",""),c=new RegExp(o[1],t);s.push(c),r.push(c)}else if(e.includes("/")){const t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");s.push(new RegExp(`^${t}`)),p.push(e)}else if(e.startsWith("@")){const t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");s.push(new RegExp(`^${t}/`)),p.push(e.endsWith("/")?e:`${e}/`)}else{const t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`^${t}(/|$)`);s.push(c),r.push(c)}}return{allowlistPatterns:s,scopePrefixes:p,scopePatterns:r}}i(buildScopePatterns,"buildScopePatterns"),u(buildScopePatterns,"buildScopePatterns");
|
package/create-webpack-dev.js
CHANGED
|
@@ -1,186 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createDevWebpackConfig = createDevWebpackConfig;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const app_plugin_1 = require("@nx/webpack/app-plugin");
|
|
6
|
-
const fs = tslib_1.__importStar(require("node:fs"));
|
|
7
|
-
const path = tslib_1.__importStar(require("node:path"));
|
|
8
|
-
const webpack_node_externals_1 = tslib_1.__importDefault(require("webpack-node-externals"));
|
|
9
|
-
const build_scope_patterns_1 = require("./build-scope-patterns");
|
|
10
|
-
const tsgo_check_plugin_1 = require("./tsgo-check-plugin");
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
12
|
-
const webpack = require('webpack');
|
|
13
|
-
class DevServerReloadPlugin {
|
|
14
|
-
constructor(port, secure = false) {
|
|
15
|
-
// When the parent terminates TLS (gateway.https), notify over https with the
|
|
16
|
-
// self-signed cert accepted — the cert is ours (basic-ssl style, cached locally).
|
|
17
|
-
this.secure = secure;
|
|
18
|
-
this.url = `${secure ? 'https' : 'http'}://localhost:${port}/webpack/reload`;
|
|
19
|
-
}
|
|
20
|
-
notify() {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
-
const mod = (this.secure ? require('node:https') : require('node:http'));
|
|
24
|
-
const req = mod.request(this.url, { method: 'POST', headers: { 'content-type': 'application/json' }, rejectUnauthorized: false }, (res) => { res.resume(); res.on('end', resolve); });
|
|
25
|
-
req.on('error', reject);
|
|
26
|
-
req.end('{}');
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
-
apply(compiler) {
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
-
compiler.hooks.done.tap('DevServerReloadPlugin', async (stats) => {
|
|
33
|
-
try {
|
|
34
|
-
if (stats.hasErrors())
|
|
35
|
-
return;
|
|
36
|
-
await this.notify();
|
|
37
|
-
console.log('[DevServerReloadPlugin] notified devserver to reload');
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
console.log('[DevServerReloadPlugin] devserver not running yet');
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
-
function createDevWebpackConfig(options) {
|
|
47
|
-
const { appRoot, outputDir, main, tsConfig, workspaceRoot, assets = [], port, memoryLimit = 8192, buildLibsFromSource = true, orgScopes = [], bundlePackages = [], additionalEntryPoints = [], nodeExternalsConfig: userNodeExternalsConfig, webpackConfigPath, } = options;
|
|
48
|
-
const { allowlistPatterns, scopePrefixes, scopePatterns } = (0, build_scope_patterns_1.buildScopePatterns)(orgScopes);
|
|
49
|
-
// Type-checking mode (LENSMCP_TYPECHECK): default = the resident fork-ts-checker pair (async,
|
|
50
|
-
// feeds the lens `error TS` service-error signal); 'off' = none (fastest, quietest — the signal
|
|
51
|
-
// is traded away); 'tsgo' = zero-resident cold re-checks via @typescript/native-preview (same
|
|
52
|
-
// signal, no idle memory — see tsgo-check-plugin.ts).
|
|
53
|
-
//
|
|
54
|
-
// tsgo still falls back to fork-ts-checker when no binary resolves — degrading gracefully beats
|
|
55
|
-
// failing a dev server — but that fallback is now an ANOMALY, not the expected "the flag shipped
|
|
56
|
-
// ahead of the devDep" state: @lensmcp/cluster DEPENDS on the compiler. So it also reports itself
|
|
57
|
-
// onto the lens bus. fork-ts-checker publishes to the CONSOLE only, so without this the
|
|
58
|
-
// `typecheck://` resources would sit at `producer: 'none'` with nothing naming the reason —
|
|
59
|
-
// the precise "looks healthy because nobody is watching" state this producer exists to end.
|
|
60
|
-
const typecheckMode = process.env.LENSMCP_TYPECHECK;
|
|
61
|
-
const tsgoBin = typecheckMode === 'tsgo' ? (0, tsgo_check_plugin_1.resolveTsgoBin)(workspaceRoot, process.env.LENSMCP_TSGO_BIN) : null;
|
|
62
|
-
if (typecheckMode === 'tsgo' && !tsgoBin) {
|
|
63
|
-
// No trailing period: `summariseProducers` renders this INSIDE a sentence it terminates itself.
|
|
64
|
-
const detail = `${tsgo_check_plugin_1.TSGO_MISSING_CAUSE}. Fell back to fork-ts-checker, which reports to the console only — ` +
|
|
65
|
-
`so typecheck:// has no producer for this project until it is fixed`;
|
|
66
|
-
console.warn(`[serve] ${options.appName}: LENSMCP_TYPECHECK=tsgo but ${detail}.`);
|
|
67
|
-
(0, tsgo_check_plugin_1.reportTsgoUnavailable)({ appName: options.appName, tsConfig, workspaceRoot, detail });
|
|
68
|
-
}
|
|
69
|
-
const useTsgo = !!tsgoBin;
|
|
70
|
-
// Build combined allowlist: orgScopes + bundlePackages + user-provided
|
|
71
|
-
const bundlePatterns = bundlePackages.map((pkg) => new RegExp(`^${pkg.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(/|$)`));
|
|
72
|
-
const combinedAllowlist = [
|
|
73
|
-
/webpack\/hot\/poll\?100/,
|
|
74
|
-
...allowlistPatterns,
|
|
75
|
-
...bundlePatterns,
|
|
76
|
-
...(userNodeExternalsConfig?.allowlist || []),
|
|
77
|
-
];
|
|
78
|
-
const config = {
|
|
79
|
-
output: {
|
|
80
|
-
path: outputDir,
|
|
81
|
-
...(process.env.NODE_ENV !== 'production' && {
|
|
82
|
-
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
|
|
83
|
-
}),
|
|
84
|
-
clean: true,
|
|
85
|
-
},
|
|
86
|
-
externals: [
|
|
87
|
-
(0, webpack_node_externals_1.default)({
|
|
88
|
-
allowlist: combinedAllowlist,
|
|
89
|
-
additionalModuleDirs: userNodeExternalsConfig?.additionalModuleDirs || [],
|
|
90
|
-
...(userNodeExternalsConfig?.importType && { importType: userNodeExternalsConfig.importType }),
|
|
91
|
-
}),
|
|
92
|
-
({ request }, callback) => {
|
|
93
|
-
// Workspace-internal absolute requests are SOURCE regardless of the
|
|
94
|
-
// bucket layout (apps/, libs/, server/, shared/, web/, …) — bundle them.
|
|
95
|
-
// The apps/libs prefix checks below stay for explicitness/back-compat.
|
|
96
|
-
if (request &&
|
|
97
|
-
path.isAbsolute(request) &&
|
|
98
|
-
request.startsWith(workspaceRoot) &&
|
|
99
|
-
!request.includes('node_modules')) {
|
|
100
|
-
return callback();
|
|
101
|
-
}
|
|
102
|
-
if (request &&
|
|
103
|
-
(request.startsWith(path.join(workspaceRoot, 'apps')) ||
|
|
104
|
-
request.startsWith(path.join(workspaceRoot, 'libs')))) {
|
|
105
|
-
return callback();
|
|
106
|
-
}
|
|
107
|
-
if (request && scopePrefixes.some((prefix) => request.startsWith(prefix))) {
|
|
108
|
-
return callback();
|
|
109
|
-
}
|
|
110
|
-
if (request && scopePatterns.some((pattern) => pattern.test(request))) {
|
|
111
|
-
return callback();
|
|
112
|
-
}
|
|
113
|
-
if (request && bundlePatterns.some((pattern) => pattern.test(request))) {
|
|
114
|
-
return callback();
|
|
115
|
-
}
|
|
116
|
-
if (request && !(request.startsWith('./') || request.startsWith('..'))) {
|
|
117
|
-
// Bare specifier: only a real node_modules package may stay external —
|
|
118
|
-
// tsconfig-path aliases (e.g. @org/contracts → workspace source) must bundle.
|
|
119
|
-
const rootSegment = request.startsWith('@')
|
|
120
|
-
? request.split('/').slice(0, 2).join('/')
|
|
121
|
-
: request.split('/')[0];
|
|
122
|
-
if (!fs.existsSync(path.join(workspaceRoot, 'node_modules', rootSegment))) {
|
|
123
|
-
return callback();
|
|
124
|
-
}
|
|
125
|
-
return callback(null, `commonjs ${request}`);
|
|
126
|
-
}
|
|
127
|
-
return callback();
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
mode: 'development',
|
|
131
|
-
devtool: 'eval-cheap-module-source-map',
|
|
132
|
-
plugins: [
|
|
133
|
-
new webpack.HotModuleReplacementPlugin(),
|
|
134
|
-
new app_plugin_1.NxAppWebpackPlugin({
|
|
135
|
-
target: 'node22',
|
|
136
|
-
compiler: 'tsc',
|
|
137
|
-
main,
|
|
138
|
-
additionalEntryPoints,
|
|
139
|
-
verbose: true,
|
|
140
|
-
sourceMap: 'eval-cheap-module-source-map',
|
|
141
|
-
mergeExternals: true,
|
|
142
|
-
externalDependencies: [],
|
|
143
|
-
memoryLimit,
|
|
144
|
-
tsConfig,
|
|
145
|
-
assets,
|
|
146
|
-
optimization: false,
|
|
147
|
-
progress: false,
|
|
148
|
-
outputHashing: 'none',
|
|
149
|
-
generatePackageJson: false,
|
|
150
|
-
watchDependencies: true,
|
|
151
|
-
// Type checking = the fork-ts-checker pair (2 worker processes, ~80MB per service) AND the
|
|
152
|
-
// source of the in-pod `error TS…` lines the gateway sniffs into the lens "service error"
|
|
153
|
-
// signal. Default ON. `LENSMCP_TYPECHECK=off` trades the signal for memory/CPU;
|
|
154
|
-
// `LENSMCP_TYPECHECK=tsgo` keeps the signal at zero resident cost (the TsgoCheckPlugin
|
|
155
|
-
// below replaces the resident pair with debounced cold native checks).
|
|
156
|
-
typeCheckOptions: process.env.LENSMCP_TYPECHECK === 'off' || useTsgo ? false : { async: true },
|
|
157
|
-
buildLibsFromSource,
|
|
158
|
-
}),
|
|
159
|
-
new DevServerReloadPlugin(port, options.httpsReload === true),
|
|
160
|
-
...(useTsgo
|
|
161
|
-
? [
|
|
162
|
-
new tsgo_check_plugin_1.TsgoCheckPlugin({
|
|
163
|
-
appName: options.appName,
|
|
164
|
-
tsConfig,
|
|
165
|
-
workspaceRoot,
|
|
166
|
-
...(process.env.LENSMCP_TSGO_BIN ? { binPath: process.env.LENSMCP_TSGO_BIN } : {}),
|
|
167
|
-
}),
|
|
168
|
-
]
|
|
169
|
-
: []),
|
|
170
|
-
],
|
|
171
|
-
snapshot: { managedPaths: [/^(.+?[\\/])?node_modules[\\/]/] },
|
|
172
|
-
watch: true,
|
|
173
|
-
watchOptions: {
|
|
174
|
-
ignored: ['**/*.env.template', '**/config.template.json', '**/*.md', '**/dist/**', '**/migrations/**'],
|
|
175
|
-
},
|
|
176
|
-
cache: { type: 'filesystem' },
|
|
177
|
-
};
|
|
178
|
-
// Apply user webpack overrides if configured
|
|
179
|
-
if (webpackConfigPath) {
|
|
180
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
181
|
-
const overrideModule = require(path.resolve(appRoot, webpackConfigPath));
|
|
182
|
-
const overrideFn = overrideModule.default || overrideModule;
|
|
183
|
-
return overrideFn(config);
|
|
184
|
-
}
|
|
185
|
-
return config;
|
|
186
|
-
}
|
|
1
|
+
"use strict";var x=Object.defineProperty;var u=(o,t)=>x(o,"name",{value:t,configurable:!0});var T=Object.defineProperty,l=u((o,t)=>T(o,"name",{value:t,configurable:!0}),"l");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createDevWebpackConfig=createDevWebpackConfig;const tslib_1=require("tslib"),app_plugin_1=require("@nx/webpack/app-plugin"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),webpack_node_externals_1=tslib_1.__importDefault(require("webpack-node-externals")),build_scope_patterns_1=require("./build-scope-patterns"),tsgo_check_plugin_1=require("./tsgo-check-plugin"),webpack=require("webpack");class DevServerReloadPlugin{static{u(this,"DevServerReloadPlugin")}static{l(this,"DevServerReloadPlugin")}constructor(t,s=!1){this.secure=s,this.url=`${s?"https":"http"}://localhost:${t}/webpack/reload`}notify(){return new Promise((t,s)=>{const i=(this.secure?require("node:https"):require("node:http")).request(this.url,{method:"POST",headers:{"content-type":"application/json"},rejectUnauthorized:!1},a=>{a.resume(),a.on("end",t)});i.on("error",s),i.end("{}")})}apply(t){t.hooks.done.tap("DevServerReloadPlugin",async s=>{try{if(s.hasErrors())return;await this.notify(),console.log("[DevServerReloadPlugin] notified devserver to reload")}catch{console.log("[DevServerReloadPlugin] devserver not running yet")}})}}function createDevWebpackConfig(o){const{appRoot:t,outputDir:s,main:i,tsConfig:a,workspaceRoot:r,assets:f=[],port:b,memoryLimit:P=8192,buildLibsFromSource:k=!0,orgScopes:w=[],bundlePackages:S=[],additionalEntryPoints:C=[],nodeExternalsConfig:p,webpackConfigPath:d}=o,{allowlistPatterns:y,scopePrefixes:E,scopePatterns:N}=(0,build_scope_patterns_1.buildScopePatterns)(w),h=process.env.LENSMCP_TYPECHECK,m=h==="tsgo"?(0,tsgo_check_plugin_1.resolveTsgoBin)(r,process.env.LENSMCP_TSGO_BIN):null;if(h==="tsgo"&&!m){const e=`${tsgo_check_plugin_1.TSGO_MISSING_CAUSE}. Fell back to fork-ts-checker, which reports to the console only \u2014 so typecheck:// has no producer for this project until it is fixed`;console.warn(`[serve] ${o.appName}: LENSMCP_TYPECHECK=tsgo but ${e}.`),(0,tsgo_check_plugin_1.reportTsgoUnavailable)({appName:o.appName,tsConfig:a,workspaceRoot:r,detail:e})}const g=!!m,v=S.map(e=>new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(/|$)`)),D=[/webpack\/hot\/poll\?100/,...y,...v,...p?.allowlist||[]],_={output:{path:s,...process.env.NODE_ENV!=="production"&&{devtoolModuleFilenameTemplate:"[absolute-resource-path]"},clean:!0},externals:[(0,webpack_node_externals_1.default)({allowlist:D,additionalModuleDirs:p?.additionalModuleDirs||[],...p?.importType&&{importType:p.importType}}),({request:e},c)=>{if(e&&path.isAbsolute(e)&&e.startsWith(r)&&!e.includes("node_modules")||e&&(e.startsWith(path.join(r,"apps"))||e.startsWith(path.join(r,"libs")))||e&&E.some(n=>e.startsWith(n))||e&&N.some(n=>n.test(e))||e&&v.some(n=>n.test(e)))return c();if(e&&!(e.startsWith("./")||e.startsWith(".."))){const n=e.startsWith("@")?e.split("/").slice(0,2).join("/"):e.split("/")[0];return fs.existsSync(path.join(r,"node_modules",n))?c(null,`commonjs ${e}`):c()}return c()}],mode:"development",devtool:"eval-cheap-module-source-map",plugins:[new webpack.HotModuleReplacementPlugin,new app_plugin_1.NxAppWebpackPlugin({target:"node22",compiler:"tsc",main:i,additionalEntryPoints:C,verbose:!0,sourceMap:"eval-cheap-module-source-map",mergeExternals:!0,externalDependencies:[],memoryLimit:P,tsConfig:a,assets:f,optimization:!1,progress:!1,outputHashing:"none",generatePackageJson:!1,watchDependencies:!0,typeCheckOptions:process.env.LENSMCP_TYPECHECK==="off"||g?!1:{async:!0},buildLibsFromSource:k}),new DevServerReloadPlugin(b,o.httpsReload===!0),...g?[new tsgo_check_plugin_1.TsgoCheckPlugin({appName:o.appName,tsConfig:a,workspaceRoot:r,...process.env.LENSMCP_TSGO_BIN?{binPath:process.env.LENSMCP_TSGO_BIN}:{}})]:[]],snapshot:{managedPaths:[/^(.+?[\\/])?node_modules[\\/]/]},watch:!0,watchOptions:{ignored:["**/*.env.template","**/config.template.json","**/*.md","**/dist/**","**/migrations/**"]},cache:{type:"filesystem"}};if(d){const e=require(path.resolve(t,d));return(e.default||e)(_)}return _}u(createDevWebpackConfig,"createDevWebpackConfig"),l(createDevWebpackConfig,"createDevWebpackConfig");
|