@spotpatch/dev-server 0.7.0 → 0.8.0
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/index.cjs +49 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +55 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -155,6 +155,7 @@ declare const DEFAULT_OPTIONS: Readonly<{
|
|
|
155
155
|
readonly graphMaxCallsites: 100;
|
|
156
156
|
readonly analysisTimeoutMs: 2000;
|
|
157
157
|
readonly reportMaxFields: 100;
|
|
158
|
+
readonly sourceMaxComponents: 256;
|
|
158
159
|
}>;
|
|
159
160
|
}>;
|
|
160
161
|
externalAgent: Readonly<{
|
|
@@ -216,7 +217,7 @@ type SourceIdFactory = () => string;
|
|
|
216
217
|
|
|
217
218
|
interface SourceRegistry {
|
|
218
219
|
register(absolutePath: string): string;
|
|
219
|
-
registerDataFlowComponents(absolutePath: string, sourceVersion: string, components: readonly DataFlowComponentAnchorInput[]):
|
|
220
|
+
registerDataFlowComponents(absolutePath: string, sourceVersion: string, components: readonly DataFlowComponentAnchorInput[]): string;
|
|
220
221
|
resolve(fileId: string): string | undefined;
|
|
221
222
|
resolveDataFlowComponent(componentSourceId: string): DataFlowComponentAnchor | undefined;
|
|
222
223
|
clear(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -155,6 +155,7 @@ declare const DEFAULT_OPTIONS: Readonly<{
|
|
|
155
155
|
readonly graphMaxCallsites: 100;
|
|
156
156
|
readonly analysisTimeoutMs: 2000;
|
|
157
157
|
readonly reportMaxFields: 100;
|
|
158
|
+
readonly sourceMaxComponents: 256;
|
|
158
159
|
}>;
|
|
159
160
|
}>;
|
|
160
161
|
externalAgent: Readonly<{
|
|
@@ -216,7 +217,7 @@ type SourceIdFactory = () => string;
|
|
|
216
217
|
|
|
217
218
|
interface SourceRegistry {
|
|
218
219
|
register(absolutePath: string): string;
|
|
219
|
-
registerDataFlowComponents(absolutePath: string, sourceVersion: string, components: readonly DataFlowComponentAnchorInput[]):
|
|
220
|
+
registerDataFlowComponents(absolutePath: string, sourceVersion: string, components: readonly DataFlowComponentAnchorInput[]): string;
|
|
220
221
|
resolve(fileId: string): string | undefined;
|
|
221
222
|
resolveDataFlowComponent(componentSourceId: string): DataFlowComponentAnchor | undefined;
|
|
222
223
|
clear(): void;
|
package/dist/index.js
CHANGED
|
@@ -2478,6 +2478,7 @@ function createSourceRegistry(options = {}) {
|
|
|
2478
2478
|
);
|
|
2479
2479
|
}
|
|
2480
2480
|
componentIdsByPath.set(normalizedPath, currentIds);
|
|
2481
|
+
return fileId;
|
|
2481
2482
|
},
|
|
2482
2483
|
resolve(fileId) {
|
|
2483
2484
|
return idToPath.get(fileId);
|
|
@@ -4161,17 +4162,33 @@ function createSpotPatchMiddleware(options) {
|
|
|
4161
4162
|
|
|
4162
4163
|
// src/server/source-registration.ts
|
|
4163
4164
|
import { timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
4164
|
-
import { lstat as lstat4, realpath as realpath6 } from "fs/promises";
|
|
4165
|
+
import { lstat as lstat4, readFile as readFile4, realpath as realpath6 } from "fs/promises";
|
|
4165
4166
|
import path8 from "path";
|
|
4166
|
-
import {
|
|
4167
|
+
import {
|
|
4168
|
+
createDataFlowSourceFilter,
|
|
4169
|
+
createDataFlowSourceVersion,
|
|
4170
|
+
createSourceFilter
|
|
4171
|
+
} from "@spotpatch/compiler";
|
|
4172
|
+
import { DEFAULT_DATA_FLOW_LIMITS as DEFAULT_DATA_FLOW_LIMITS2 } from "@spotpatch/shared";
|
|
4167
4173
|
import { z as z2 } from "zod";
|
|
4168
|
-
var REGISTRATION_BODY_LIMIT_BYTES =
|
|
4174
|
+
var REGISTRATION_BODY_LIMIT_BYTES = DEFAULT_DATA_FLOW_LIMITS2.protocolRequestMaxBytes;
|
|
4169
4175
|
var REGISTRATION_IDENTITY_PATTERN = /^[A-Za-z0-9_-]{16,128}$/u;
|
|
4176
|
+
var DATA_FLOW_IDENTITY_PATTERN = /^[A-Za-z0-9_-]{1,128}$/u;
|
|
4170
4177
|
var INTERNAL_SECRET_HEADER = "x-spotpatch-internal";
|
|
4171
4178
|
var FORBIDDEN_SOURCE_SEGMENTS = /* @__PURE__ */ new Set([".next", "node_modules"]);
|
|
4172
4179
|
var registrationRequestSchema = z2.strictObject({
|
|
4173
4180
|
epoch: z2.string().regex(REGISTRATION_IDENTITY_PATTERN),
|
|
4174
|
-
resourcePath: z2.string().min(1).max(3072)
|
|
4181
|
+
resourcePath: z2.string().min(1).max(3072),
|
|
4182
|
+
dataFlow: z2.strictObject({
|
|
4183
|
+
sourceVersion: z2.string().regex(DATA_FLOW_IDENTITY_PATTERN),
|
|
4184
|
+
components: z2.array(
|
|
4185
|
+
z2.strictObject({
|
|
4186
|
+
componentSourceId: z2.string().regex(DATA_FLOW_IDENTITY_PATTERN),
|
|
4187
|
+
line: z2.number().int().positive().max(1e7),
|
|
4188
|
+
column: z2.number().int().positive().max(1e7)
|
|
4189
|
+
})
|
|
4190
|
+
).max(DEFAULT_DATA_FLOW_LIMITS2.sourceMaxComponents)
|
|
4191
|
+
}).optional()
|
|
4175
4192
|
});
|
|
4176
4193
|
function getSingleHeader3(request, name) {
|
|
4177
4194
|
const value = request.headers[name.toLowerCase()];
|
|
@@ -4235,6 +4252,33 @@ async function createSourceRegistrationService(input) {
|
|
|
4235
4252
|
}
|
|
4236
4253
|
const root = await realpath6(input.root);
|
|
4237
4254
|
const sourceFilter = createSourceFilter(root, input.options);
|
|
4255
|
+
const dataFlowFilter = createDataFlowSourceFilter(root, input.options);
|
|
4256
|
+
const registrationQueues = /* @__PURE__ */ new Map();
|
|
4257
|
+
async function registerCurrentSource(sourcePath, dataFlow) {
|
|
4258
|
+
if (dataFlow === void 0) {
|
|
4259
|
+
return input.registry.register(sourcePath);
|
|
4260
|
+
}
|
|
4261
|
+
let fileId;
|
|
4262
|
+
const previous = registrationQueues.get(sourcePath) ?? Promise.resolve();
|
|
4263
|
+
const current = previous.catch(() => void 0).then(async () => {
|
|
4264
|
+
const currentSource = await readFile4(sourcePath, "utf8");
|
|
4265
|
+
if (createDataFlowSourceVersion(currentSource) !== dataFlow.sourceVersion) {
|
|
4266
|
+
return;
|
|
4267
|
+
}
|
|
4268
|
+
fileId = input.registry.registerDataFlowComponents(
|
|
4269
|
+
sourcePath,
|
|
4270
|
+
dataFlow.sourceVersion,
|
|
4271
|
+
dataFlow.components
|
|
4272
|
+
);
|
|
4273
|
+
});
|
|
4274
|
+
registrationQueues.set(sourcePath, current);
|
|
4275
|
+
await current.finally(() => {
|
|
4276
|
+
if (registrationQueues.get(sourcePath) === current) {
|
|
4277
|
+
registrationQueues.delete(sourcePath);
|
|
4278
|
+
}
|
|
4279
|
+
});
|
|
4280
|
+
return fileId;
|
|
4281
|
+
}
|
|
4238
4282
|
const handler = (request, response) => {
|
|
4239
4283
|
const handle = async () => {
|
|
4240
4284
|
const contentType = getSingleHeader3(request, "content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
@@ -4255,16 +4299,18 @@ async function createSourceRegistrationService(input) {
|
|
|
4255
4299
|
const sourcePath = await resolveAuthorizedSource(
|
|
4256
4300
|
root,
|
|
4257
4301
|
parsed.data.resourcePath,
|
|
4258
|
-
(absolutePath) => sourceFilter.shouldTransform(absolutePath, "<")
|
|
4302
|
+
(absolutePath) => parsed.data.dataFlow === void 0 ? sourceFilter.shouldTransform(absolutePath, "<") : dataFlowFilter.shouldTransform(absolutePath, "")
|
|
4259
4303
|
);
|
|
4260
4304
|
if (sourcePath === void 0) {
|
|
4261
4305
|
writeJson3(response, 403, { ok: false });
|
|
4262
4306
|
return;
|
|
4263
4307
|
}
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4308
|
+
const fileId = await registerCurrentSource(sourcePath, parsed.data.dataFlow);
|
|
4309
|
+
if (fileId === void 0) {
|
|
4310
|
+
writeJson3(response, 409, { ok: false });
|
|
4311
|
+
return;
|
|
4312
|
+
}
|
|
4313
|
+
writeJson3(response, 200, { epoch: input.registryEpoch, fileId });
|
|
4268
4314
|
};
|
|
4269
4315
|
void handle().catch(() => {
|
|
4270
4316
|
if (!response.headersSent) {
|