@juspay/neurolink 12.44.4 → 12.44.6

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.
@@ -0,0 +1,334 @@
1
+ import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, writeFileSync, renameSync, mkdirSync, } from "node:fs";
2
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { applyPatch, structuredPatch } from "diff";
5
+ const BASELINE_NAME = ".neurolink-proxy-baseline.json";
6
+ const MAX_FILES = 4096;
7
+ const MAX_FILE_BYTES = 2 * 1024 * 1024;
8
+ const MAX_TOTAL_BYTES = 64 * 1024 * 1024;
9
+ const MAX_CHANGED_FILES = 64;
10
+ /** Locate the package without importing its executable or provider graph. */
11
+ export function proxyPackageRoot(entryScript) {
12
+ let directory = dirname(realpathSync(entryScript));
13
+ for (;;) {
14
+ const manifest = join(directory, "package.json");
15
+ if (existsSync(manifest)) {
16
+ let value;
17
+ try {
18
+ value = JSON.parse(readFileSync(manifest, "utf8"));
19
+ }
20
+ catch {
21
+ throw new Error("Proxy package manifest is unreadable or invalid");
22
+ }
23
+ if (value &&
24
+ typeof value === "object" &&
25
+ "name" in value &&
26
+ value.name === "@juspay/neurolink") {
27
+ return directory;
28
+ }
29
+ }
30
+ const parent = dirname(directory);
31
+ if (parent === directory) {
32
+ throw new Error("Proxy package manifest not found");
33
+ }
34
+ directory = parent;
35
+ }
36
+ }
37
+ function sorted(value) {
38
+ if (Array.isArray(value)) {
39
+ return value.map(sorted);
40
+ }
41
+ if (value && typeof value === "object") {
42
+ return Object.fromEntries(Object.entries(value)
43
+ .sort(([a], [b]) => a.localeCompare(b))
44
+ .map(([key, item]) => [key, sorted(item)]));
45
+ }
46
+ return value;
47
+ }
48
+ function safePath(path) {
49
+ return (!isAbsolute(path) &&
50
+ !path.includes("\\") &&
51
+ path
52
+ .split("/")
53
+ .every((part) => part !== "" && part !== "." && part !== ".."));
54
+ }
55
+ function runtimePath(path, entryRelative) {
56
+ return (safePath(path) &&
57
+ /\.(?:[cm]?js|json)$/.test(path) &&
58
+ (path === entryRelative ||
59
+ (path.startsWith("dist/") && !path.startsWith("dist/browser/")) ||
60
+ path.startsWith("scripts/observability/")));
61
+ }
62
+ /** Bounded baseline of shipped proxy code; operator config and dependencies are excluded. */
63
+ export function snapshotProxyPackage(selection) {
64
+ const root = proxyPackageRoot(selection.entryScript);
65
+ const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
66
+ // Release numbers and npm bookkeeping are not runtime compatibility edits.
67
+ const comparable = Object.fromEntries(Object.entries(manifest).filter(([key]) => key !== "version" && key !== "gitHead" && !key.startsWith("_")));
68
+ const entryRelative = relative(root, realpathSync(selection.entryScript))
69
+ .split("\\")
70
+ .join("/");
71
+ if (!safePath(entryRelative)) {
72
+ throw new Error("Proxy executable escapes package");
73
+ }
74
+ const files = {};
75
+ let bytes = 0;
76
+ const read = (path) => {
77
+ if (!runtimePath(path, entryRelative) || Object.hasOwn(files, path)) {
78
+ return;
79
+ }
80
+ const file = join(root, path);
81
+ const stat = lstatSync(file);
82
+ if (!stat.isFile() || stat.isSymbolicLink()) {
83
+ throw new Error(`Proxy runtime file is not a regular file: ${path}`);
84
+ }
85
+ if (stat.size > MAX_FILE_BYTES ||
86
+ bytes + stat.size > MAX_TOTAL_BYTES ||
87
+ Object.keys(files).length >= MAX_FILES) {
88
+ throw new Error("Proxy runtime baseline exceeds its size limit");
89
+ }
90
+ const data = readFileSync(file);
91
+ files[path] = new TextDecoder("utf-8", {
92
+ fatal: true,
93
+ ignoreBOM: true,
94
+ }).decode(data);
95
+ bytes += data.length;
96
+ };
97
+ const walk = (path) => {
98
+ if (!existsSync(join(root, path))) {
99
+ return;
100
+ }
101
+ if (lstatSync(join(root, path)).isSymbolicLink()) {
102
+ throw new Error(`Proxy runtime directory is a symbolic link: ${path}`);
103
+ }
104
+ for (const item of readdirSync(join(root, path), {
105
+ withFileTypes: true,
106
+ }).sort((a, b) => a.name.localeCompare(b.name))) {
107
+ const next = `${path}/${item.name}`;
108
+ if (next === "dist/browser" || item.name === "node_modules") {
109
+ continue;
110
+ }
111
+ if (item.isSymbolicLink()) {
112
+ throw new Error(`Proxy runtime path is a symbolic link: ${next}`);
113
+ }
114
+ if (item.isDirectory()) {
115
+ walk(next);
116
+ }
117
+ else {
118
+ read(next);
119
+ }
120
+ }
121
+ };
122
+ walk("dist");
123
+ walk("scripts/observability");
124
+ read(entryRelative);
125
+ return {
126
+ schemaVersion: 1,
127
+ version: selection.version,
128
+ manifest: JSON.stringify(sorted(comparable)),
129
+ entryRelative,
130
+ files,
131
+ };
132
+ }
133
+ /** Invalid or missing baseline must never be silently replaced with edited files. */
134
+ export function readProxyPackageBaseline(selection) {
135
+ const path = join(proxyPackageRoot(selection.entryScript), BASELINE_NAME);
136
+ if (!existsSync(path)) {
137
+ return null;
138
+ }
139
+ const stat = lstatSync(path);
140
+ if (!stat.isFile() ||
141
+ stat.isSymbolicLink() ||
142
+ stat.size > MAX_TOTAL_BYTES * 2) {
143
+ throw new Error("Proxy package baseline is invalid");
144
+ }
145
+ let value;
146
+ try {
147
+ value = JSON.parse(readFileSync(path, "utf8"));
148
+ }
149
+ catch {
150
+ throw new Error("Proxy package baseline is unreadable or invalid");
151
+ }
152
+ if (value.schemaVersion !== 1 ||
153
+ typeof value.version !== "string" ||
154
+ typeof value.manifest !== "string" ||
155
+ typeof value.entryRelative !== "string" ||
156
+ !safePath(value.entryRelative) ||
157
+ !value.files ||
158
+ typeof value.files !== "object" ||
159
+ Array.isArray(value.files)) {
160
+ throw new Error("Proxy package baseline is invalid");
161
+ }
162
+ let bytes = 0;
163
+ const entries = Object.entries(value.files);
164
+ if (entries.length > MAX_FILES) {
165
+ throw new Error("Proxy package baseline exceeds its size limit");
166
+ }
167
+ for (const [name, content] of entries) {
168
+ if (!runtimePath(name, value.entryRelative) ||
169
+ typeof content !== "string" ||
170
+ Buffer.byteLength(content) > MAX_FILE_BYTES) {
171
+ throw new Error("Proxy package baseline contains an invalid file");
172
+ }
173
+ bytes += Buffer.byteLength(content);
174
+ }
175
+ if (bytes > MAX_TOTAL_BYTES) {
176
+ throw new Error("Proxy package baseline exceeds its size limit");
177
+ }
178
+ return value;
179
+ }
180
+ export function writeProxyPackageBaseline(selection, baseline) {
181
+ const path = join(proxyPackageRoot(selection.entryScript), BASELINE_NAME);
182
+ const temporary = `${path}.${randomUUID()}.tmp`;
183
+ writeFileSync(temporary, JSON.stringify(baseline), {
184
+ mode: 0o600,
185
+ flag: "wx",
186
+ });
187
+ renameSync(temporary, path);
188
+ }
189
+ /** Operator supplies the pristine base for a legacy local build; this does not activate it. */
190
+ export function captureProxyPackageBaseline(base, patched) {
191
+ const original = snapshotProxyPackage(base);
192
+ const current = snapshotProxyPackage(patched);
193
+ if (original.manifest !== current.manifest ||
194
+ original.entryRelative !== current.entryRelative) {
195
+ throw new Error("Local package metadata differs from its base; runtime polyfills cannot change dependencies or the executable");
196
+ }
197
+ const existing = readProxyPackageBaseline(patched);
198
+ if (existing &&
199
+ (existing.manifest !== original.manifest ||
200
+ JSON.stringify(sorted(existing.files)) !==
201
+ JSON.stringify(sorted(original.files)))) {
202
+ throw new Error("A different proxy package baseline is already recorded");
203
+ }
204
+ const changed = changedProxyRuntimeFiles(original, current);
205
+ writeProxyPackageBaseline(patched, original);
206
+ return changed;
207
+ }
208
+ export function changedProxyRuntimeFiles(base, current) {
209
+ if (base.manifest !== current.manifest ||
210
+ base.entryRelative !== current.entryRelative) {
211
+ throw new Error("Local package metadata changed; refusing upgrade rather than discarding it");
212
+ }
213
+ return [
214
+ ...new Set([...Object.keys(base.files), ...Object.keys(current.files)]),
215
+ ]
216
+ .sort()
217
+ .filter((path) => base.files[path] !== current.files[path]);
218
+ }
219
+ function occurrences(content, lines) {
220
+ if (!lines.length) {
221
+ return 0;
222
+ }
223
+ const haystack = content.split("\n");
224
+ let count = 0;
225
+ for (let start = 0; start + lines.length <= haystack.length; start++) {
226
+ if (lines.every((line, offset) => line === haystack[start + offset])) {
227
+ count++;
228
+ }
229
+ if (count > 1) {
230
+ break;
231
+ }
232
+ }
233
+ return count;
234
+ }
235
+ /** Apply exact local hunks, leaving independent upstream changes intact. */
236
+ export function reconcileProxyPackagePolyfills(base, local, candidate) {
237
+ const changed = changedProxyRuntimeFiles(base, local);
238
+ if (changed.length > MAX_CHANGED_FILES) {
239
+ throw new Error("Proxy polyfill exceeds the 64-file compatibility diff limit");
240
+ }
241
+ const files = {};
242
+ const report = {
243
+ applied: [],
244
+ alreadyIncluded: [],
245
+ };
246
+ for (const path of changed) {
247
+ if (!runtimePath(path, candidate.entryRelative)) {
248
+ throw new Error(`Proxy polyfill path is outside the candidate runtime: ${path}`);
249
+ }
250
+ const before = base.files[path];
251
+ const after = local.files[path];
252
+ const upstream = candidate.files[path];
253
+ if (upstream === after) {
254
+ report.alreadyIncluded.push(path);
255
+ continue;
256
+ }
257
+ if (upstream === before) {
258
+ files[path] = after ?? null;
259
+ report.applied.push(path);
260
+ continue;
261
+ }
262
+ if (before === undefined ||
263
+ after === undefined ||
264
+ upstream === undefined ||
265
+ before === "" ||
266
+ after === "") {
267
+ throw new Error(`Proxy polyfill conflicts with the release: ${path}`);
268
+ }
269
+ const patch = structuredPatch(path, path, before, after, "", "", {
270
+ context: 3,
271
+ timeout: 1000,
272
+ maxEditLength: 20_000,
273
+ });
274
+ if (!patch || patch.hunks.length > 128) {
275
+ throw new Error(`Proxy polyfill exceeds its diff budget: ${path}`);
276
+ }
277
+ let content = upstream;
278
+ let applied = false;
279
+ for (const hunk of patch.hunks) {
280
+ const oldLines = hunk.lines
281
+ .filter((line) => line[0] === " " || line[0] === "-")
282
+ .map((line) => line.slice(1));
283
+ const newLines = hunk.lines
284
+ .filter((line) => line[0] === " " || line[0] === "+")
285
+ .map((line) => line.slice(1));
286
+ const oldMatches = occurrences(content, oldLines);
287
+ const newMatches = occurrences(content, newLines);
288
+ if (newMatches === 1 && oldMatches === 0) {
289
+ continue;
290
+ }
291
+ if (oldMatches !== 1 || newMatches !== 0) {
292
+ throw new Error(`Proxy polyfill conflicts with the release: ${path}`);
293
+ }
294
+ const result = applyPatch(content, { ...patch, hunks: [hunk] }, { fuzzFactor: 0 });
295
+ if (result === false) {
296
+ throw new Error(`Proxy polyfill conflicts with the release: ${path}`);
297
+ }
298
+ content = result;
299
+ applied = true;
300
+ }
301
+ if (applied) {
302
+ files[path] = content;
303
+ report.applied.push(path);
304
+ }
305
+ else {
306
+ report.alreadyIncluded.push(path);
307
+ }
308
+ }
309
+ return { files, report };
310
+ }
311
+ /** Writes are confined to a new staged copy, never the serving package. */
312
+ export function writeProxyPolyfilledFile(root, path, content) {
313
+ root = realpathSync(root);
314
+ if (!safePath(path)) {
315
+ throw new Error("Invalid proxy polyfill path");
316
+ }
317
+ const target = resolve(root, path);
318
+ if (!target.startsWith(`${realpathSync(root)}/`)) {
319
+ throw new Error("Proxy polyfill escapes its package");
320
+ }
321
+ // A candidate cannot redirect a patch through a symlinked parent.
322
+ let parent = dirname(target);
323
+ while (parent !== root) {
324
+ if (existsSync(parent) && lstatSync(parent).isSymbolicLink()) {
325
+ throw new Error("Proxy polyfill parent is a symbolic link");
326
+ }
327
+ parent = dirname(parent);
328
+ }
329
+ if (existsSync(target) && lstatSync(target).isSymbolicLink()) {
330
+ throw new Error("Proxy polyfill target is a symbolic link");
331
+ }
332
+ mkdirSync(dirname(target), { recursive: true });
333
+ writeFileSync(target, content);
334
+ }
@@ -4437,6 +4437,32 @@ export type ProxyStagedInstallOptions = {
4437
4437
  outputBytes: number;
4438
4438
  }) => void;
4439
4439
  };
4440
+ /** Original proxy runtime files retained before any local compatibility edits. */
4441
+ export type ProxyPackageBaseline = {
4442
+ schemaVersion: 1;
4443
+ version: string;
4444
+ manifest: string;
4445
+ entryRelative: string;
4446
+ files: Record<string, string>;
4447
+ };
4448
+ /** A candidate carries only local diff hunks that its release still needs. */
4449
+ export type ProxyPackagePolyfillReport = {
4450
+ applied: string[];
4451
+ alreadyIncluded: string[];
4452
+ };
4453
+ /** Staged upgrade that reconciles recorded local edits before publication. */
4454
+ export type ProxyPackageUpgradeOptions = ProxyStagedInstallOptions & {
4455
+ activePackage: ProxyPackageSelection;
4456
+ isCurrentOwner?: () => boolean;
4457
+ onPolyfills?: (report: ProxyPackagePolyfillReport) => void;
4458
+ };
4459
+ /** Capture a trusted baseline for a locally patched package without activation. */
4460
+ export type ProxyPolyfillArgs = {
4461
+ action: "capture";
4462
+ base: string;
4463
+ patched: string;
4464
+ format: "text" | "json";
4465
+ };
4440
4466
  /** Saved launchd settings retained when installing the service again. */
4441
4467
  export type ProxyServiceInstallSettings = {
4442
4468
  envFile?: string;