Comparing version 16.3.3 to 16.3.4
@@ -1,4 +0,18 @@ | ||
import { MockRequest, MockResponse, MockResponseHandler, PushEvent } from './dvlp.js'; | ||
import { | ||
MockPushEvent, | ||
MockPushStream, | ||
MockRequest, | ||
MockResponse, | ||
MockResponseHandler, | ||
PushEvent, | ||
} from './dvlp.js'; | ||
export { MockRequest, MockResponse, MockResponseHandler, PushEvent }; | ||
export { | ||
MockPushEvent, | ||
MockPushStream, | ||
MockRequest, | ||
MockResponse, | ||
MockResponseHandler, | ||
PushEvent, | ||
}; | ||
@@ -25,2 +39,10 @@ export namespace testBrowser { | ||
/** | ||
* Register mock push "events" for "stream" | ||
*/ | ||
function mockPushEvents( | ||
stream: string | MockPushStream, | ||
events: MockPushEvent | Array<MockPushEvent>, | ||
onSendCallback?: (data: any) => void, | ||
): () => void; | ||
/** | ||
* Push data to WebSocket/EventSource clients | ||
@@ -27,0 +49,0 @@ * A string passed as `event` will be handled as a named mock push event |
@@ -21,3 +21,2 @@ // src/mock/mock-client.js | ||
let networkDisabled = false; | ||
let reroute = false; | ||
window.XMLHttpRequest.prototype.open = function open(method, href) { | ||
@@ -31,3 +30,3 @@ const hrefAndMock = matchHref(href); | ||
const mockResponse = resolveMockResponse(mockData); | ||
this.send = function send() { | ||
xhr.send = function send() { | ||
if (mockResponse.status === 0) { | ||
@@ -82,7 +81,5 @@ return; | ||
window.fetch = new Proxy(window.fetch, { | ||
apply: function(target, ctx, args) { | ||
apply(target, ctx, args) { | ||
const options = args[1] || {}; | ||
const hrefAndMock = matchHref(args[0]); | ||
const href = hrefAndMock[0]; | ||
const mockData = hrefAndMock[1]; | ||
const [href, mockData] = matchHref(args[0]); | ||
args[0] = href; | ||
@@ -113,6 +110,6 @@ if (mockData) { | ||
} else if (mockData.callback) { | ||
return Reflect.apply(target, ctx, args).then(function(response) { | ||
return Reflect.apply(target, ctx, args).then((response) => { | ||
setTimeout(mockData.callback, 0); | ||
return response; | ||
}).catch(function(err) { | ||
}).catch((err) => { | ||
setTimeout(mockData.callback, 0); | ||
@@ -130,9 +127,29 @@ throw err; | ||
construct: function(target, args) { | ||
if (!args[0].includes("dvlpreload")) { | ||
args[0] = matchHref(args[0])[0]; | ||
const stream = args[0]; | ||
const [href, mockData] = matchHref(args[0]); | ||
const isLocal = mockData && mockData.handlers !== void 0; | ||
if (mockData) { | ||
console.log( | ||
"mocking EventSource response (with remote data) for: " + args[0] | ||
`mocking EventSource response (with ${isLocal ? "local" : "remote"} data) for: ` + args[0] | ||
); | ||
} | ||
return Reflect.construct(target, args); | ||
args[0] = href; | ||
const es = Reflect.construct(target, args); | ||
if (isLocal) { | ||
es.addEventListener = new Proxy(es.addEventListener, { | ||
apply(target2, ctx, args2) { | ||
const [event, callback] = args2; | ||
if (event !== "open" && event !== "error") { | ||
mockData.handlers[event] = callback; | ||
} | ||
return Reflect.apply(target2, ctx, args2); | ||
} | ||
}); | ||
Object.defineProperty(mockData.handlers, "onmessage", { | ||
get() { | ||
return es.onmessage; | ||
} | ||
}); | ||
} | ||
return es; | ||
} | ||
@@ -144,7 +161,37 @@ }); | ||
construct: function(target, args) { | ||
args[0] = matchHref(args[0])[0]; | ||
console.log( | ||
"mocking WebSocket response (with remote data) for: " + args[0] | ||
); | ||
return Reflect.construct(target, args); | ||
const [href, mockData] = matchHref(args[0]); | ||
const isLocal = mockData && mockData.handlers !== void 0; | ||
if (mockData) { | ||
console.log( | ||
`mocking WebSocket response (with ${isLocal ? "local" : "remote"} data) for: ` + args[0] | ||
); | ||
} | ||
args[0] = href; | ||
const ws = Reflect.construct(target, args); | ||
if (isLocal) { | ||
ws.addEventListener = new Proxy(ws.addEventListener, { | ||
apply(target2, ctx, args2) { | ||
const [event, callback] = args2; | ||
if (event === "message") { | ||
mockData.handlers.message = callback; | ||
} | ||
return Reflect.apply(target2, ctx, args2); | ||
} | ||
}); | ||
Object.defineProperty(mockData.handlers, "onmessage", { | ||
get() { | ||
return ws.onmessage; | ||
} | ||
}); | ||
} | ||
if (mockData && mockData.callback) { | ||
ws.send = new Proxy(ws.send, { | ||
apply(target2, ctx, args2) { | ||
const result = Reflect.apply(target2, ctx, args2); | ||
mockData.callback(args2[0]); | ||
return result; | ||
} | ||
}); | ||
} | ||
return ws; | ||
} | ||
@@ -159,10 +206,7 @@ }); | ||
* Disable all external network connections | ||
* and optionally reroute all external requests to this server | ||
* | ||
* @param { boolean } [rerouteAllRequests] | ||
* @returns { void } | ||
*/ | ||
disableNetwork: function disableNetwork(rerouteAllRequests) { | ||
disableNetwork() { | ||
networkDisabled = true; | ||
reroute = rerouteAllRequests || false; | ||
}, | ||
@@ -174,5 +218,4 @@ /** | ||
*/ | ||
enableNetwork: function enableNetwork() { | ||
enableNetwork() { | ||
networkDisabled = false; | ||
reroute = false; | ||
}, | ||
@@ -188,9 +231,9 @@ /** | ||
*/ | ||
mockResponse: function mockResponse(req, res, once, onMockCallback) { | ||
const ignoreSearch = req && typeof req === "object" && req.url !== void 0 && req.type === void 0 && req.ignoreSearch || false; | ||
mockResponse(req, res, once = false, onMockCallback) { | ||
const ignoreSearch = isMockRequest(req) && req.ignoreSearch || false; | ||
const url = getUrl(req); | ||
const originRegex = new RegExp( | ||
url.origin.replace(/http:|https:/, "https?:").replace("ws:", "wss?:").replace("//", "\\/\\/") | ||
url.origin.replace(/http:|https:/, "https?:").replace("//", "\\/\\/") | ||
); | ||
const pathRegex = new RegExp(url.pathname.replace(/\//g, "\\/")); | ||
const pathRegex = new RegExp(url.pathname.replaceAll(/\//g, "\\/")); | ||
if (typeof res !== "function") { | ||
@@ -205,3 +248,3 @@ if (res && !res.body) { | ||
ignoreSearch, | ||
once: once || false, | ||
once, | ||
originRegex, | ||
@@ -213,3 +256,3 @@ pathRegex, | ||
cache.unshift(mock); | ||
return function() { | ||
return () => { | ||
remove(mock); | ||
@@ -219,2 +262,65 @@ }; | ||
/** | ||
* Register mock push "events" for "stream" | ||
* | ||
* @param { string | MockPushStream } stream | ||
* @param { MockPushEvent | Array<MockPushEvent> } events | ||
* @param { () => void } [onSendCallback] | ||
* @returns { () => void } remove mock instance | ||
*/ | ||
mockPushEvents(stream, events2, onSendCallback) { | ||
if (!Array.isArray(events2)) { | ||
events2 = [events2]; | ||
} | ||
const ignoreSearch = isMockRequest(stream) && stream.ignoreSearch || false; | ||
const url = getUrl(stream); | ||
const originRegex = new RegExp( | ||
url.origin.replace(/ws:|wss:/, "wss?:").replace("//", "\\/\\/") | ||
); | ||
const pathRegex = new RegExp(url.pathname.replaceAll(/\//g, "\\/")); | ||
const type = originRegex.source.includes("ws") ? "ws" : "es"; | ||
const protocol = isMockRequest(stream) && stream.protocol || type; | ||
const eventsData = {}; | ||
for (const event of events2) { | ||
if (event.name) { | ||
const options = { delay: 0, ...event.options, protocol }; | ||
const sequence = []; | ||
if (event.sequence) { | ||
for (const sequenceEvent of event.sequence) { | ||
sequence.push({ | ||
message: sequenceEvent.message || "", | ||
options: { delay: 0, ...sequenceEvent.options, protocol } | ||
}); | ||
} | ||
} else { | ||
sequence.push({ | ||
name: event.name, | ||
message: event.message || "", | ||
options | ||
}); | ||
} | ||
if (options.connect) { | ||
const connectEvent = eventsData.connect || []; | ||
connectEvent.push(...sequence); | ||
eventsData.connect = connectEvent; | ||
} | ||
eventsData[event.name] = sequence; | ||
} | ||
} | ||
const mock = { | ||
href: url.href, | ||
originRegex, | ||
pathRegex, | ||
search: url.search, | ||
ignoreSearch, | ||
events: eventsData, | ||
handlers: {}, | ||
callback: onSendCallback | ||
}; | ||
this.cache.unshift(mock); | ||
return () => { | ||
delete mock.handlers; | ||
remove(mock); | ||
}; | ||
}, | ||
/** | ||
* Trigger EventSource/WebSocket event | ||
@@ -225,16 +331,55 @@ * | ||
*/ | ||
pushEvent: function pushEvent(stream, event) { | ||
originalFetch("/dvlp/push-event", { | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json", | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify({ stream, event }) | ||
}); | ||
async pushEvent(stream, event) { | ||
const [href, mockData] = matchHref(stream); | ||
if (!mockData) { | ||
throw Error(`no push event mocks registerd for ${stream}`); | ||
} | ||
if (!mockData.handlers) { | ||
return originalFetch("/dvlp/push-event", { | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json", | ||
"Content-Type": "application/json" | ||
}, | ||
// TODO: handle binary? | ||
body: JSON.stringify({ stream, event }) | ||
}); | ||
} | ||
if (typeof event === "string") { | ||
const eventSequence = mockData.events[event]; | ||
if (eventSequence) { | ||
for (const event2 of eventSequence) { | ||
const { | ||
message, | ||
options: { delay = 0, ...options } | ||
} = event2; | ||
await sleep(delay); | ||
const handler = mockData.handlers[options.event] || mockData.handlers.message || mockData.handlers.onmessage; | ||
const msg = new MessageEvent("message", { | ||
data: message, | ||
lastEventId: options.id || "" | ||
}); | ||
handler(msg); | ||
} | ||
} | ||
} else { | ||
const { message, options = {} } = event; | ||
const handler = mockData.handlers[options.event] || mockData.handlers.message || mockData.handlers.onmessage; | ||
const msg = new MessageEvent("message", { | ||
data: typeof message !== "string" ? JSON.stringify(message) : message, | ||
lastEventId: options.id || "" | ||
}); | ||
handler(msg); | ||
} | ||
} | ||
}; | ||
function sleep(duration) { | ||
return new Promise((resolve) => setTimeout(resolve, duration)); | ||
} | ||
function isMockRequest(req) { | ||
return req && typeof req === "object" && req.url !== void 0 && req.type === void 0; | ||
} | ||
function matchHref(href) { | ||
const url = getUrl(href); | ||
if (url.pathname === "/dvlpreload") { | ||
if (url.pathname === "/dvlp/reload") { | ||
return [href]; | ||
@@ -260,6 +405,3 @@ } | ||
} else if (location.host !== url.host) { | ||
if (reroute) { | ||
url.host = location.host; | ||
href = url.href; | ||
} else if (networkDisabled) { | ||
if (networkDisabled) { | ||
throw Error( | ||
@@ -311,2 +453,5 @@ "network connections disabled. Unable to request " + parseOriginalHref(href) | ||
function getUrl(href) { | ||
if (href instanceof URL) { | ||
return href; | ||
} | ||
href = typeof href === "string" ? href : href.url; | ||
@@ -396,2 +541,13 @@ return new URL(href, location.href); | ||
/** | ||
* Register mock push "events" for "stream" | ||
* | ||
* @param { string | MockPushStream } stream | ||
* @param { MockPushEvent | Array<MockPushEvent> } events | ||
* @param { (data: any) => void } [onSendCallback] | ||
* @returns { () => void } remove mock instance | ||
*/ | ||
mockPushEvents(stream, events, onSendCallback) { | ||
return window.dvlp.mockPushEvents(stream, events, onSendCallback); | ||
}, | ||
/** | ||
* Trigger EventSource/WebSocket event | ||
@@ -398,0 +554,0 @@ * |
@@ -44,3 +44,2 @@ /// <reference types="node" /> | ||
maxAgeLong: string; | ||
reloadEndpoint: string; | ||
serverStartTimeout: number; | ||
@@ -333,3 +332,3 @@ testing: boolean; | ||
name?: string; | ||
message: string | { [key: string]: any }; | ||
message: Buffer | string | Record<string, any>; | ||
options: MockPushEventOptions & { | ||
@@ -362,5 +361,5 @@ protocol?: string; | ||
export interface MockResponse { | ||
body: string | { [key: string]: any }; | ||
body: string | Record<string, any>; | ||
hang?: boolean; | ||
headers?: { [key: string]: any }; | ||
headers?: Record<string, any>; | ||
error?: boolean; | ||
@@ -400,3 +399,3 @@ missing?: boolean; | ||
name: string; | ||
message?: string | { [key: string]: any }; | ||
message?: Buffer | string | Record<string, any>; | ||
sequence?: Array<MockPushEvent>; | ||
@@ -427,3 +426,3 @@ options?: MockPushEventOptions; | ||
on(event: string, callback: (event: { data: string }) => void): void; | ||
send(msg: string, options?: PushEventOptions): void; | ||
send(msg: Buffer | string, options?: PushEventOptions): void; | ||
removeAllListeners(): void; | ||
@@ -438,14 +437,14 @@ close(): void; | ||
export interface PushEventOptions { | ||
event?: string; | ||
id?: string; | ||
namespace?: string; | ||
protocol?: string; | ||
} | ||
export interface PushEvent { | ||
message: string | { [key: string]: any }; | ||
message: Buffer | string | Record<string, unknown>; | ||
options?: PushEventOptions; | ||
} | ||
export interface PushEventOptions { | ||
id?: string; // EventSource ID | ||
event?: string; // EventSource event OR Socket.IO event | ||
namespace?: string; // Socket.IO namespace | ||
protocol?: string; // Socket.IO protocol | ||
} | ||
// src/resolver/_.d.ts | ||
@@ -530,5 +529,5 @@ export interface Package { | ||
/** | ||
* The `Mocks` instance, if initialised | ||
* The `Mocks` instance | ||
*/ | ||
readonly mocks?: Mocks; | ||
readonly mocks: Mocks; | ||
/** | ||
@@ -605,2 +604,3 @@ * The localhost port number | ||
events: MockPushEvent | Array<MockPushEvent>, | ||
onSendCallback?: (data: any) => void, | ||
): void; | ||
@@ -607,0 +607,0 @@ /** |
{ | ||
"name": "dvlp", | ||
"version": "16.3.3", | ||
"version": "16.3.4", | ||
"description": "A no-nonsense dev server toolkit to help you develop quickly and easily for the web", | ||
@@ -24,3 +24,3 @@ "type": "module", | ||
"commander": "^12.0.0", | ||
"esbuild": "~0.20.2" | ||
"esbuild": "~0.21.1" | ||
}, | ||
@@ -33,15 +33,15 @@ "devDependencies": { | ||
"@types/mocha": "^10.0.6", | ||
"@types/node": "^20.12.7", | ||
"@types/node": "^20.12.11", | ||
"@types/platform": "^1.3.6", | ||
"@types/send": "^0.17.4", | ||
"@typescript-eslint/eslint-plugin": "^7.6.0", | ||
"@typescript-eslint/parser": "^7.6.0", | ||
"chai": "^5.1.0", | ||
"@typescript-eslint/eslint-plugin": "^7.8.0", | ||
"@typescript-eslint/parser": "^7.8.0", | ||
"chai": "^5.1.1", | ||
"chalk": "^5.3.0", | ||
"chokidar": "^3.6.0", | ||
"cjs-module-lexer": "^1.2.3", | ||
"cjs-module-lexer": "^1.3.1", | ||
"cross-env": "^7.0.3", | ||
"debug": "^4.3.4", | ||
"electron": "29.3.0", | ||
"es-module-lexer": "~1.5.0", | ||
"electron": "30.0.3", | ||
"es-module-lexer": "~1.5.2", | ||
"eslint": "^8.57.0", | ||
@@ -51,7 +51,7 @@ "eslint-config-prettier": "^9.1.0", | ||
"fast-glob": "^3.3.2", | ||
"fastify": "^4.26.2", | ||
"fastify": "^4.27.0", | ||
"faye-websocket": "~0.11.4", | ||
"husky": "^9.0.11", | ||
"lint-staged": "^15.2.2", | ||
"lit-html": "^3.1.2", | ||
"lit-html": "^3.1.3", | ||
"mocha": "^10.4.0", | ||
@@ -62,5 +62,5 @@ "path-to-regexp": "^6.2.2", | ||
"prettier": "^3.2.5", | ||
"react": "^18.2.0", | ||
"react": "^18.3.1", | ||
"resolve.exports": "^2.0.2", | ||
"terser": "^5.30.3", | ||
"terser": "^5.31.0", | ||
"typescript": "^5.4.5" | ||
@@ -67,0 +67,0 @@ }, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1230841
32679
+ Added@esbuild/aix-ppc64@0.21.5(transitive)
+ Added@esbuild/android-arm@0.21.5(transitive)
+ Added@esbuild/android-arm64@0.21.5(transitive)
+ Added@esbuild/android-x64@0.21.5(transitive)
+ Added@esbuild/darwin-arm64@0.21.5(transitive)
+ Added@esbuild/darwin-x64@0.21.5(transitive)
+ Added@esbuild/freebsd-arm64@0.21.5(transitive)
+ Added@esbuild/freebsd-x64@0.21.5(transitive)
+ Added@esbuild/linux-arm@0.21.5(transitive)
+ Added@esbuild/linux-arm64@0.21.5(transitive)
+ Added@esbuild/linux-ia32@0.21.5(transitive)
+ Added@esbuild/linux-loong64@0.21.5(transitive)
+ Added@esbuild/linux-mips64el@0.21.5(transitive)
+ Added@esbuild/linux-ppc64@0.21.5(transitive)
+ Added@esbuild/linux-riscv64@0.21.5(transitive)
+ Added@esbuild/linux-s390x@0.21.5(transitive)
+ Added@esbuild/linux-x64@0.21.5(transitive)
+ Added@esbuild/netbsd-x64@0.21.5(transitive)
+ Added@esbuild/openbsd-x64@0.21.5(transitive)
+ Added@esbuild/sunos-x64@0.21.5(transitive)
+ Added@esbuild/win32-arm64@0.21.5(transitive)
+ Added@esbuild/win32-ia32@0.21.5(transitive)
+ Added@esbuild/win32-x64@0.21.5(transitive)
+ Addedesbuild@0.21.5(transitive)
- Removed@esbuild/aix-ppc64@0.20.2(transitive)
- Removed@esbuild/android-arm@0.20.2(transitive)
- Removed@esbuild/android-arm64@0.20.2(transitive)
- Removed@esbuild/android-x64@0.20.2(transitive)
- Removed@esbuild/darwin-arm64@0.20.2(transitive)
- Removed@esbuild/darwin-x64@0.20.2(transitive)
- Removed@esbuild/freebsd-arm64@0.20.2(transitive)
- Removed@esbuild/freebsd-x64@0.20.2(transitive)
- Removed@esbuild/linux-arm@0.20.2(transitive)
- Removed@esbuild/linux-arm64@0.20.2(transitive)
- Removed@esbuild/linux-ia32@0.20.2(transitive)
- Removed@esbuild/linux-loong64@0.20.2(transitive)
- Removed@esbuild/linux-mips64el@0.20.2(transitive)
- Removed@esbuild/linux-ppc64@0.20.2(transitive)
- Removed@esbuild/linux-riscv64@0.20.2(transitive)
- Removed@esbuild/linux-s390x@0.20.2(transitive)
- Removed@esbuild/linux-x64@0.20.2(transitive)
- Removed@esbuild/netbsd-x64@0.20.2(transitive)
- Removed@esbuild/openbsd-x64@0.20.2(transitive)
- Removed@esbuild/sunos-x64@0.20.2(transitive)
- Removed@esbuild/win32-arm64@0.20.2(transitive)
- Removed@esbuild/win32-ia32@0.20.2(transitive)
- Removed@esbuild/win32-x64@0.20.2(transitive)
- Removedesbuild@0.20.2(transitive)
Updatedesbuild@~0.21.1